繁体   English   中英

推迟在应用运行angularjs上创建控制器/服务

[英]Defer creation of controllers/services on app run angularjs

每次更改路线时,我都会检查是否使用当前登录的用户详细信息设置了变量,如果未设置此变量,我将直接重定向到登录页面。

现在,我正在尝试实现某种“记住我”功能,因此,每次路由更改时,如果不存在变量用户,而不是重定向到登录页面,我都会在本地存储中检查“ authtoken”,如果设置了if,我将调用将身份验证令牌传递到服务器的检查功能,该功能将返回用户,并且该应用程序的工作方式与手动登录后相同(返回与检查功能相同的用户)。

我敢肯定这不是最好的方法。

如果重新加载页面,则第一件事是运行检查功能,该功能将authtoken发送到服务器并等待响应(如果用户存在,则将值分配给rootscope中的变量)。

我有不同的服务,例如,使用rootscope中的变量

angular.module('myApp')
    .service('AdminService', function AdminService($rootScope, $http, StorageService) {
    var authtoken = StorageService.get('authtoken');
    var clientId = $rootScope.loggedUser.id;

当然,当check函数运行时,它会等待响应,但是正在实例化该服务,并且$ rootScope.loggedUser.id不存在。

如何通知应用程序等待检查功能收到响应?

这是我的代码

....
}).run(function($rootScope, $location, AuthService, StorageService) {

var intended = $location.path();  

AuthService.check().success(function(data) {
    if(data.user) {
       $rootScope.loggedUser = data.user;
       $location.path(intended);
    } else $location.path('login');
});
$rootScope.$on('$routeChangeStart', function() {

  if($rootScope.loggedUser) {
  ....

例如,如果用户将页面“ myapp.com/#/admin/users”添加为书签,则我不想重定向到登录名(如果我在本地存储中拥有authtoken),但是这会导致控制器实例化,使用需要尚未填充的$ rootScope.loggedUser.id的服务。

我想仅在页面(重新)加载时运行功能检查(而不是在用户每次更改路线时都运行)。

如果您需要服务电话来检查您的身份验证令牌,我建议您重新检查您的设计。 身份验证令牌通常在其中存储了过期时间,因此您无需致电服务器就可以检查自己是否在过期期内。 您不会损害安全性,因为身份验证令牌是由服务器签名的,并且在您进行服务器调用以进行任何有用的操作时都会经过验证。 因此,在正常情况下,不需要单独的check调用。

但是,如果您坚持认为,最好用路由的resolve属性来处理此用例。 但是,这意味着,每个关心用户登录状态的路由都必须定义一个resolve属性。 这并不意味着您必须在每次更改路线时都调用该服务。

与其使用$rootScope.loggedUser来存储用户, AuthService将其由AuthService缓存并通过resolve参数注入。

因此,您可以执行以下操作:

$routeProvider
   .when("some/secure/route", {
          controller: "SecureCtrl",
          resolve: {
             user: AuthService.checkUser
          }
        });

在您的AuthService中:

...
checkUser: function(){
  var deferred = $q.defer();

  if (cachedUser){
     deferred.resolve(cachedUser);
  } else {

     AuthService.check().success(
        function(data){
           // cachedUseris defined at AuthService's scope
           cachedUser = data.user;
           deferred.resolve(data.user);
        });
  }

  return deferred.promise;
}

然后,在您的控制器中:

.controller("SecureCtrl", function(user){
   $scope.userId = user.id;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM