2016-08-05 74 views
0

是否可以在路由器的解析屬性中使用promise? 我想使用服務來檢查用戶是否有權訪問路徑解析中的頁面。 例子:解決路由解析屬性中的承諾

  $stateProvider 
      .state('user', { 
       url: '/user', 
       templateUrl: 'app/views/user/views/user.html', 
       controller: 'UserCtrl', 
       controllerAs: 'vm', 
       resolve: { 
        security: ['$state', 'userService','messageService','$location', function ($state, userService, messageService, $location) { 
         userService.checkUserAndRole("user").then(function(data){ 
         var data = userService.checkUserAndRole("user"); 
         if (data.access === false) { 
          messageService.errorMsg(data.message); 
          var route = data.route ? data.route:$location.path(); 
          $state.go(route); 
         }); 
        }] 
       } 
      }); 

我使用$ Q服務userService返回一個承諾

function checkUserAndRole(page){ 
     var defer = $q.defer(); 
     var response = {}; 
     if(!ROLE[page]){ 
      response.access = false; 
      response.message = "Page is not defined in ROLE config. Please tell admin to correct this!"; 
      response.route = "login"; 
      defer.resolve(response); 
     } 

     if(!user.roles){ 
      response.access = false; 
      response.message = "Logged in user does not seem to have any role data defined. That is why you are redirected"; 
      response.route = "/"; 
      defer.resolve(response); 
     } 

     if(!helperService.arrayIntersect(ROLE[page],user.roles)){ 
      response.access = false; 
      response.message = "You don't have a permission to access '/"+page+"' url"; 
      defer.resolve(response); 
     } 

     response.access = true; 
     response.message = ""; 
     response.route = ""; 

     return defer.promise; 
    } 

如果我不從服務使用承諾,但返回的數據立即一切運作良好,但是,刷新我仍然得到無效的結果,因爲來自服務的用戶數據通過$ http獲取,並且在解決路由時數據還沒有到達。

+0

您好vodich,問題是在決心,你需要它來返回一個承諾,在此刻你的安全屬性什麼都沒有返回。因此,要麼將$ q添加到安全函數中,並在完成所有邏輯後返回defer.promise,要麼更改checkUserAndRole函數以處理狀態更改。 – George

+0

好吧,但我不想將任何數據傳遞給控制器​​,只需要在決心做這個東西,那就是它。 – vodich

回答

1

解析函數使用promise,但返回對解析器函數的承諾是很重要的。

$stateProvider 
    .state('user', { 
     url: '/user', 
     templateUrl: 'app/views/user/views/user.html', 
     controller: 'UserCtrl', 
     controllerAs: 'vm', 
     resolve: { 
      security: ['$state', 'userService','messageService','$location', function ($state, userService, messageService, $location) { 
       //RETURN the promise 
       return (
        userService.checkUserAndRole("user") 
         .then(function(data){ 
          if (data.access === false) { 
           messageService.errorMsg(data.message); 
           var route = data.route ? data.route:$location.path(); 
           $state.go(route); 
         }); 
       ); 
      }] 

     } 
    }); 

由於未能回報承諾對分解功能,路由器解析securitynull無需等待承諾完成。


另外,checkUserAndRole功能未能解決$q.defer在沒有任何的if條件屬實的情況。代碼需要重寫。

function checkUserAndRole(page){ 
    var response = {}; 
    var promise = $q.when(); 
    if(!ROLE[page]){ 
     response.access = false; 
     response.message = "Page is not defined in ROLE config. Please tell admin to correct this!"; 
     response.route = "login"; 
     promise = $q.when(response); 
    } else if(!user.roles) { 
     response.access = false; 
     response.message = "Logged in user does not seem to have any role data defined. That is why you are redirected"; 
     response.route = "/"; 
     promise = $q.when(response); 
    } else if(!helperService.arrayIntersect(ROLE[page],user.roles)){ 
     response.access = false; 
     response.message = "You don't have a permission to access '/"+page+"' url"; 
     promise = $q.when(response); 
    } else { 
     response.access = true; 
     response.message = ""; 
     response.route = ""; 
     promise = $q.when(response); 
    }; 

    return promise; 
} 

避免$q.defer,因爲它容易出現編碼錯誤。而是使用$q.when來創建一個值的承諾。

+0

很好,今天學了一兩件事,謝謝! – vodich