在$ stateChangeStart触发之前解析抽象父级中的promise

时间:2017-11-16 15:57:45

标签: javascript angularjs promise angular-ui-router angular-promise

我尝试在加载Home子状态之前解析抽象父状态中的某些服务器端数据。我想确保在状态data.rule功能中使用用户的全名进行检查。但是,使用console.log语句,我可以在"完成"之前看到userFullName打印为控制台的空字符串。 factory.privilegeData方法中的语句。

修改

父解析中的数据是来自服务器的安全数据,在初始化任何控制器之前,该数据需要全局可用。此处仅列出一个子状态(为了便于阅读),但login之外的所有状态都是抽象父级的子级。一旦父进程结算完成,数据就存储在$rootScope中,并用于通过每个状态中的data.rule函数确定访问权限。

config.js

更新:以下答案我已经更新了父/子状态,但我仍然遇到同样的问题:

        .state('app', {
            url:'',
            abstract: true,
            template: '<div ui-view class="slide-animation"></div>',
            resolve:{
                privileges: ['$q', 'privilegesService', function($q, privilegesService){
                    console.log('from parent resolve');
                    return privilegesService.getPrivileges()
                                            .then(privilegesService.privilegesData)
                                            .catch(privilegesService.getPrivilegesError);
                }]
            }
        })
        .state('app.home', {
            url: '/home',
            templateUrl: 'app/components/home/home.html',
            controller: 'HomeController',
            controllerAs: 'vm',
            parent: 'app',
            resolvePolicy: {when:'LAZY', async: 'WAIT'},
            authenticate: true,
            data:{
                rule: function($rootScope){
                    console.log("from home state data rule");
                    return true;
                }
            }                   
        })

privilegesService.js

factory.getPrivileges = function () {
    console.log('from server call');
    var queryString = "&cmd=privilege&action=user";
    return $http.get(config.serviceBaseUri + queryString);
};  

factory.privilegesData = function(priv){
    console.log('from privilege data');
    if(priv && priv.data) {
        $rootScope.userFullName = priv.data.firstName + ' ' + priv.data.lastName;
    }
        console.log('done');
};

根据上面的console个参数,我得到以下输出。我需要from home state data rule最后发生......

enter image description here

...因为我使用data.rule函数的结果来授权每个州。以下是我的$stateChangeStart方法

中的.run

app.route.js

    $rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
        if(toState.authenticate){
            if(authService.authKeyExists()){
                if(toState.data.rule($rootScope)){
                    navigationService.addNavObject("activity", {
                        summary : "Page navigation",
                        page : $location.absUrl().replace("#/", "")
                    });
                } else {
                    $state.go('app.home');
                }
            } else {
                event.preventDefault();
                $state.go('login');
            }   
        }
    });

1 个答案:

答案 0 :(得分:1)

子状态需要父状态作为依赖关系才能使其等待加载,即使它没有直接使用。 Source

您必须尝试以下内容:

.state('app.home', {
    url: '/home',
    templateUrl: 'app/components/home/home.html',
    controller: 'HomeController',
    controllerAs: 'vm',
    parent: 'app',
    authenticate: true,
    data:{
        rule: function($rootScope){
            console.log($rootScope.userFullName);
            return true;
        }
    }                   
})

你可以使用属性 resolvepolicy 并将其设置为LAZY,状态的LAZY结算将等待父状态的结果在开始加载之前完成。