如何在AngularJS中存储当前用户上下文?


92

我有一个AuthService,用于登录用户,它返回一个用户json对象。我要做的是设置该对象,并使所有更改都反映在整个应用程序中(登录/注销状态),而无需刷新页面。

我将如何使用AngularJS做到这一点?

Answers:


180

实现此目的的最简单方法是使用服务。例如:

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();
  });
});

然后,当然可以使用您认为合适的信息;例如,在指令,模板等中。您可以在菜单控制器等中重复此操作(根据您需要执行的操作)。更改服务状态时,所有这些都将自动更新。

任何更具体的内容都取决于您的实现。

希望这可以帮助!


28
@ChrisNicola实际上,在AngularJS中,所有服务都是单例。因此,服务是在第一次被请求时(即,由控制器或其他服务)创建的,随后对它的所有请求均返回完全相同的实例。
Josh David Miller

2
可以,但是作为一项功能,我们可以从公共API中删除将信息存储到私有API中的内部方式。这使得以后的重构更加容易。但是该函数仍将返回布尔值。
Josh David Miller

7
这可能是一个愚蠢的问题……但是,如果用户刷新页面会发生什么?登录信息会丢失吗?
汤巴(Tomba)

10
@Tomba这是一个很好的问题。:-)实际上,信息在刷新时会丢失。通常,您需要将一些会话信息存储在cookie中。设置时,也可以检查该会话信息AuthService。这不仅有助于刷新页面,而且还有助于在新标签页中打开链接的人。
乔什·戴维·米勒

2
@PixMach您是100%正确的学习曲线。您的问题将取决于很多具体情况,但是这里有一些常规模式。保持关注点分离:与启动登录相关的UI与auth本身是分离的,而auth本身与auth的状态是分离的,而auth的状态则与可能依赖于该状态的任何菜单分离。导航/菜单通常最好由单个控制器处理,并且嵌套状态(la ui-router)和路由解析是使auth控件保持DRY的好方法。你写的东西听起来不错。
乔什·大卫·米勒

5

我要补充一下Josh的良好回应,因为AuthService通常是任何人都感兴趣的(例如,如果没有人登录,则登录视图之外的任何人都应该消失),也许更简单的选择是使用$rootScope.$broadcast('loginStatusChanged', isLoggedIn);(1 )(2),而相关方(例如控制者)会使用收听$scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; }

(1)$rootScope作为服务的论点被注入

(2)请注意,在异步登录操作的可能情况下,您需要通过将Angular包含在$rootScope.$apply()函数中来通知Angular广播将改变事物。

现在,谈到在每个控制器中保留用户上下文,您可能不愿意在每个控制器中监听登录更改,并且可能更喜欢仅在最顶层的登录控制器中监听,然后将其他可识别登录的控制器添加为子控件/嵌入式控制器。这样,子级控制器将能够看到继承的父级$ scope属性,例如您的用户上下文。


4
因对工厂功能的错误解释而被投票。在您发布答案之前的几个月中,此评论已解决了这种误解。
Rhys van der Waerden 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.