Javascript 如何在使用angular_Desive注销之前保持全局当前用户?
如何创建自己的全局可访问的服务,该服务在页面加载时仅通过Javascript 如何在使用angular_Desive注销之前保持全局当前用户?,javascript,angularjs,devise,angular-ui-router,angular-services,Javascript,Angularjs,Devise,Angular Ui Router,Angular Services,如何创建自己的全局可访问的服务,该服务在页面加载时仅通过currentUser()调用服务器一次,如果用户已登录,则保留该服务并向控制器或状态提供数据,直到注销? 现在,我在许多州或控制器中多次解析currentUser(),我在文档中发现:有可能创建自己的服务,但我不知道如何以正确的方式处理此问题 e、 g在ui路由器中,我有两个服务器调用,只有在加载页面时才足够: .state('login', { url: '/login', templateUrl: 'auth/_login.h
currentUser()调用服务器一次,如果用户已登录,则保留该服务并向控制器或状态提供数据,直到注销?
现在,我在许多州或控制器中多次解析currentUser()
,我在文档中发现:有可能创建自己的服务,但我不知道如何以正确的方式处理此问题
e、 g在ui路由器中,我有两个服务器调用,只有在加载页面时才足够:
.state('login', {
url: '/login',
templateUrl: 'auth/_login.html',
controller: 'AuthCtrl',
onEnter: [
'$state', 'Auth',
function($state, Auth) {
Auth.currentUser().then(function() {
$state.go('home');
});
}
]
})
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
onEnter: [
'$state', 'Auth',
function($state, Auth) {
Auth.currentUser().then(function(user) {}, function(err) {
$state.go('home');// user not logged in
});
}
]
})
或者每次在NavController中调用下一个服务器时:
app.controller('NavController', [
'$state', '$scope', 'Auth', function($state, $scope, Auth) {
$scope.signedIn = Auth.isAuthenticated;
$scope.logout = Auth.logout; // logout function
Auth.currentUser().then(function(user) {
$scope.user = user;
});
$scope.$on('devise:login', function(e, user) {
$scope.user = user;
});
$scope.$on('devise:logout', function(e, user) {
$scope.user = {};
$state.go("home");
});
}
]);
我发现类似的问题没有答案:我不得不在一个大型Angular应用程序中处理用户身份验证问题,并发现本文非常有用:
具体到“如何使其只发生一次”:
- 您可以在app.run块中调用服务的init()
- 将其添加为应用程序外部状态的
解析
要求(如果使用嵌套状态)
表示用户登录状态的UserService
服务可以很好地在整个应用程序中共享状态。登录和注销功能可以通过该服务公开,用户的详细信息也可以存储在这里。定义扩展$resource
的UserApi
,也可能有助于将实际的HTTP关注点与管理用户状态分开
本文还讨论了其他一些问题:页面刷新的持久状态,以及只有用户登录时才能访问的站点区域。我们知道,factory是一个单例对象,基本上用于数据共享。我们可以将它作为依赖项注入任何控制器和函数
.所以这也可能解决你的问题。将此服务注入状态解析块,检查用户是否存在,如果不存在,则调用工厂的fetch user函数
app.factory("User", function($http, $q, $rootScope) {
var user = null;
return {
fetchUser: function() {
/*your ajax call that return current user*/
user = YOUR_SERVER_RESPONSE;
return user;
},
getUser : function(){
return user;
},
setUser : function(u){
user = u;
}
}
}))
您的状态配置块如下所示
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
resolve : function(User){
if(User.getUser()){
return User.getUser();
}else{
return User.fetchUser();
}
}
})
我通过在主HTML页面底部添加以下JavaScript(jQuery)代码,解决了angular当前用户信息的问题:
$("meta[name=current_user]").data('current_user', {
id: <%=j current_user.id.to_s %>,
username: "<%=j current_user.full_name.to_s %>"
});
这是我的工厂代码,供用户使用(再次使用coffeescript):
如果您有任何问题,请告诉我。将用户详细信息保存在全局中。用户使用控制器或服务中的“全局”模块
当您必须访问用户时,请使用全局访问。用户编辑:更改某些部件,以便与angular\u设备模块一起使用
通常,我使用的是这里提供的解决方案(),它描述了如何检查每个HTTP调用的用户是否登录
如果用户已登录,则检查加载情况
我将创建一个名为“User”的附加服务(因为服务是单例的),定义一些方法,例如save()和get(),将用户保存到服务单例中,并在必要时返回它。
使用“checkLoggedIn”功能,您可以为您的路由定义一个“resolve”选项,如果承诺得到解决,则用户可以访问受限页面 您是否可以控制后端登录服务器?我将发布一个简单而常见的解决方案,但需要一个额外的服务器端功能。@FerTo我正在使用Ruby on Rails,所以我想将它与服务结合起来。哦,好吧,你应该“忽略”我的代码。好吧,我已经研究了angular_设备模块,看起来你可以使用我的“解决方案”将更改代码。我不想构建新服务,因此在这种情况下,这是与angular\u DeVICE
合作的有趣概念,如果这种方法可以通过ui路由器中的User.fetchUser()
解决Auth
服务的链接承诺,我将使用它。@luzny然后查看我的答案如果您只想检查它而不创建新服务,只需使用您的rootScope即可。我以前添加过完全相同的解决方案。正如您所描述的,您只需要检查“页面加载”,并将信息提供给其他每个服务/控制器。最简单的解决方案是使用rootScope,但我更喜欢使用基本用户Service@luzny是的,这种方法在连锁承诺中非常有效。我用这个概念是我的项目。“解析”每个块可能与要首先解析的前一个块有依赖关系,并且其工作正常。我在使用oclazyload和refresh应用程序时尝试过这一点。(当前状态为N level
)
# Grab User Info
current_user = angular.element("meta[name=current_user]").data 'current_user'
# Stop Here if you Have the Info you Need
$scope.user = current_user
# **** OR Get More Info if User is Logged In
if current_user.id is not undefined
$scope.user = User.get {id: current_user.id}
# In order to prevent minification from effecting the code
# must wrap functions as arrays and pass in the variables as
# strings before the function call
app.factory "User", ["$resource", ($resource) ->
$resource("/api/angular/users/:id",
{ id: "@id" },
{
update: { method: "PUT" }
})
]
myApp.config(['$routeProvider','$locationProvider',
function($routeProvider, $locationProvider) {
//================================================
// Check if the user is connected
//================================================
var checkLoggedin = function($q, $rootScope, Auth, User){
// Initialize a new promise
var deferred = $q.defer();
Auth.currentUser().then(function(userObj){
deferred.resolve();
//option a: just save the user object into the $rootScope
$rootScope.User = userObj;
//option b: create a factory 'User' and a method 'save()' which parses the JSON returned from your Server
User.save(userObj);
}, function(error){
deferred.reject();
});
return deferred.promise;
};
//================================================
// Define all the routes
//================================================
$routeProvider
//Start page, where the user gets a list of registered SO and can add new ones
.when('/', {
templateUrl: 'templates/index.html',
controller: 'indexCtrl',
resolve: {
loggedin: checkLoggedin
}
})
.when('/login', {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
})
// do more here
.otherwise({
redirectTo: '/'
});
}]).run(function($rootScope, $http){
//Do some initial tasks or set some values
});