【发布时间】:2012-12-21 19:18:37
【问题描述】:
我有一个 AuthService,它登录一个用户,它返回一个用户 json 对象。我想要做的是设置该对象并在应用程序中反映所有更改(登录/注销状态),而无需刷新页面。
我将如何使用 AngularJS 完成此任务?
【问题讨论】:
标签: angularjs
我有一个 AuthService,它登录一个用户,它返回一个用户 json 对象。我想要做的是设置该对象并在应用程序中反映所有更改(登录/注销状态),而无需刷新页面。
我将如何使用 AngularJS 完成此任务?
【问题讨论】:
标签: angularjs
实现此目的的最简单方法是使用服务。例如:
app.factory( 'AuthService', function() {
var currentUser;
return {
login: function() { ... },
logout: function() { ... },
isLoggedIn: function() { ... },
currentUser: function() { return currentUser; }
...
};
});
然后您可以在任何控制器中引用它。以下代码监视服务中值的更改(通过调用指定的函数),然后将更改的值同步到范围。
app.controller( 'MainCtrl', function( $scope, AuthService ) {
$scope.$watch( AuthService.isLoggedIn, function ( isLoggedIn ) {
$scope.isLoggedIn = isLoggedIn;
$scope.currentUser = AuthService.currentUser();
});
});
然后,当然,您可以按照您认为合适的方式使用这些信息;例如在指令、模板等中。您可以在菜单控制器等中重复此操作(根据您需要执行的操作)。当您更改服务的状态时,它们都会自动更新。
更具体的内容取决于您的实施。
希望这会有所帮助!
【讨论】:
AuthService 时也可以检查该会话信息。这不仅有助于页面刷新,还有助于在新标签页中打开链接。
ui-router) 和路由解析是保持身份验证控件 DRY 的好方法。你写的听起来很对。
我会修改 Josh 的良好响应,补充一点,因为 AuthService 通常会引起任何人的兴趣(例如,如果没有人登录,除了登录视图之外的任何人都应该消失),也许更简单的替代方法是通知相关方使用$rootScope.$broadcast('loginStatusChanged', isLoggedIn); (1) (2),而相关方(例如控制器)将使用$scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; } 进行监听。
(1) $rootScope 作为服务的参数注入
(2) 请注意,在异步登录操作的可能情况下,您需要通过将广播包含在 $rootScope.$apply() 函数中来通知 Angular 广播将改变事物。
现在,说到在每个/许多控制器中保留用户上下文,您可能不乐意监听每个控制器中的登录更改,并且可能更喜欢只在最顶层的登录控制器中监听,然后添加其他登录感知控制器作为这个的孩子/嵌入式控制器。这样,子控制器将能够看到继承的父 $scope 属性,例如您的用户上下文。
【讨论】: