如何跟踪angularJS控制器中的当前用户?

时间:2016-02-08 19:15:12

标签: angularjs angularjs-service angularjs-controller

工厂/服务:

  angular.module('phoenix-template')
  .factory('User', ['$http', function($http){

      function current(){
        $http.get('http://localhost:4000/api/current_user').then(function(res){
          return res.data;
        })
    }

    this.currentUser = current();

  }]);
})();

控制器:

 (function(){
  'use strict';

  angular.module('phoenix-template')
  .controller('NavCtrl', ['$scope','User', function($scope, User){

    $scope.currentUser = User.currentUser;

    $scope.$watch( 'currentUser', function () {
          User.currentUser = $scope.currentUser;
      });

  }]);
})();

我正在跟踪后端的当前用户,但我想跟踪控制器中当前用户的角度以用于显示目的等。

但是,我显然是在犯这个错误......

提示,帮助,非常感谢。

3 个答案:

答案 0 :(得分:2)

我相信你感到困惑的是factoryservice在角度上是不一样的。

  • 每次注射都会创建一个工厂
  • 服务是单身,只在角度应用的生命周期内创建一次。

在这种情况下,服务是注入控制器的最佳选择。第一个访问它将实现服务器的用户数据。然后,使用该服务的其余控制器将使用相同的服务实例,因此没有为每个控制器转到服务器的开销。

这是代码。该服务使用函数检索用户,但将结果保存到本地字段,这样它只被调用一次。然后,您的控制器可以调用该函数来检索它(如果添加一些检查逻辑,甚至可以直接访问该字段)。

(function(){
    angular.module('phoenix-template')
      .service('ngUserService', ['$http', function($http){

        var me = this;
        function getUser(callback) {
            // if the user has already been retrieved then do not do it again, just return the retrieved instance
            if(me.currentUser)
                calback(me.currentUser);
            // retrieve the currentUser and set it as a property on the service
            $http.get('http://localhost:4000/api/current_user').then(function(res){
              // set the result to a field on the service
              me.currentUser = res.data;
              // call the callback with the retrieved user
              callback(me.currentUser);
            });
        }
        return {getUser:getUser}
      }]);
    })();

控制器代码

    (function(){
      'use strict';

      angular.module('phoenix-template')
      .controller('NavCtrl', ['$scope','ngUserService', function($scope, ngUserService){
        // call to get the user and set it to your scope variable
        ngUserService.getUser(function(user){$scope.currentUser = user;});

  }]);
})();

答案 1 :(得分:1)

您可以使用$ cookies来存储用户名,令牌等用户数据。您可以在此处阅读文档https://docs.angularjs.org/api/ngCookies/service/ $ cookies

从后端服务获取用户对象后,使用$ cookies存储它,然后在需要时获取该值。

例如,您重新加载页面,然后在app.run阶段,从$ cookie获取该用户对象并存储在某些服务或$ rootScope中

我在示例应用中做了一些事情,我不记得它是100%好还是没有,但它会有所帮助

(function () {
'use strict';

var app = angular.module('app');
app.run(runFunction);

runFunction.$inject = ['$rootScope', '$state', '$cookies', '$window'];

/* @ngInject */
function runFunction($rootScope, $state, $cookies, $window) {
    //// Set User
    var user = $cookie.get('user')
    /* 
     Or you can do something
     if ($window.sessionStorage["user"]) {
        $rootScope.user = JSON.parse($window.sessionStorage["user"]);
     }
    */
    if (user) {
        $rootScope.user = JSON.parse(user);
    } else {
        $rootScope.user = {
            id: 0,
            username: 'Anonymous'
        };
    }

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
        var isAuthenticate = toState.authenticate;
        if (isAuthenticate && !$rootScope.user.token) {
            event.preventDefault();
    alert('Please login first');
            $state.go('login');
    });
}
})();

答案 2 :(得分:1)

我发现我们没有谈论在浏览器内存中保存数据,如localStorage和Cookies。 我明白了,你想以某种方式从后端观察状态。 这是可能的,但是对于性能,最好不要在所有摘要周期中执行此操作。 我建议设置间隔 - 不要太少,不要使网络过载,不要太大,以保持当前的信息跟踪。

Here是关于角度间隔的问题的答案。我认为这可以帮助。 这个解决方案可以这样实现:

.controller('NavCtrl', function($scope, User,$interval){
     $scope.loadCurrentUser = function (){
            $scope.currentUser = User.currentUser;
      };

   //Put in interval, first trigger after 10 seconds 
   $interval(function(){
      $scope.loadCurrentUser();
   }, 10000);    

   //invoke initialy
   $scope.loadCurrentUser();
  });

我的代码我删除了依赖注入。我建议使用工具自动解决名为ng-annotate的依赖注入。