【问题标题】:How do I store a current user context in AngularJS?如何在 AngularJS 中存储当前用户上下文?
【发布时间】:2012-12-21 19:18:37
【问题描述】:

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

我将如何使用 AngularJS 完成此任务?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

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

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

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

    更具体的内容取决于您的实施。

    希望这会有所帮助!

    【讨论】:

    • @ChrisNicola 实际上,在 AngularJS 中,所有服务都是单例的。因此,该服务在第一次被请求时创建(即由控制器或其他服务),并且所有后续请求都返回完全相同的实例。
    • 可能是这样,但作为一个函数,我们可以删除我们如何将信息从公共 API 存储到私有 API 的内部结构。这使得以后的重构更加容易。但该函数仍会返回一个布尔值。
    • 这可能是一个愚蠢的问题...但是如果用户刷新页面会发生什么 - 登录信息会丢失吗?
    • @Tomba 这是个好问题。 :-) 事实上,信息在刷新时丢失了。通常,您需要在 cookie 中存储 一些 会话信息。设置AuthService 时也可以检查该会话信息。这不仅有助于页面刷新,还有助于在新标签页中打开链接。
    • @PixMach 关于学习曲线,你是 100% 正确的。您的问题将取决于很多具体情况,但这里有一些一般模式。保持关注点分离:与启动登录相关的 UI 与身份验证本身是分开的,身份验证本身与身份验证的状态是分开的,身份验证的状态与可能依赖于所述状态的任何菜单是分开的。导航/菜单通常最好由单个控制器处理,嵌套状态 (a la ui-router) 和路由解析是保持身份验证控件 DRY 的好方法。你写的听起来很对。
    【解决方案2】:

    我会修改 Josh 的良好响应,补充一点,因为 AuthService 通常会引起任何人的兴趣(例如,如果没有人登录,除了登录视图之外的任何人都应该消失),也许更简单的替代方法是通知相关方使用$rootScope.$broadcast('loginStatusChanged', isLoggedIn); (1) (2),而相关方(例如控制器)将使用$scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; } 进行监听。

    (1) $rootScope 作为服务的参数注入

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

    现在,说到在每个/许多控制器中保留用户上下文,您可能不乐意监听每个控制器中的登录更改,并且可能更喜欢只在最顶层的登录控制器中监听,然后添加其他登录感知控制器作为这个的孩子/嵌入式控制器。这样,子控制器将能够看到继承的父 $scope 属性,例如您的用户上下文。

    【讨论】:

    • 因对工厂函数的错误解释而被否决。在您发布答案之前的几个月内,this comment 已经解决了这种误解。
    猜你喜欢
    • 1970-01-01
    • 2014-08-15
    • 2020-09-02
    • 2017-09-23
    • 2023-03-30
    • 2021-06-05
    • 1970-01-01
    • 2019-08-05
    相关资源
    最近更新 更多