【问题标题】:Resolve promise in route resolve property解决路由解析属性中的承诺
【发布时间】:2016-08-05 14:45:12
【问题描述】:

是否可以在路由器的 resolve 属性中使用 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);
                        });
                    }]
                }
            });

我在 userService 中使用 $q 服务来返回一个承诺

    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 获取的,并且当路由时数据还不存在解决。

【问题讨论】:

  • 嗨,vodich,问题出在解决方案中,您需要它来返回一个承诺,目前您的安全属性没有返回任何内容。因此,要么将 $q 添加到安全函数并在完成所有逻辑后返回 defer.promise,要么更改 checkUserAndRole 函数以处理状态更改
  • 好的,但我不想将任何数据传递给控制器​​,只需要在解析中做这些事情就可以了。

标签: angularjs


【解决方案1】:

Resolve 函数使用 Promise,但将 Promise返回到 resolver 函数很重要。

$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);
                        });
                );
            }]

        }
    });

由于未能返回对解析器函数的承诺,路由器将 security 解析为 null 而无需等待承诺完成。


if 条件都不为真的情况下,checkUserAndRole 函数也无法解析$q.defer。代码需要重写。

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 从值创建承诺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-17
    • 2014-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多