簡體   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