2016-08-05 42 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