Angularjs 第二次未调用Resolve

Angularjs 第二次未调用Resolve,angularjs,angular-ui-router,ionic,Angularjs,Angular Ui Router,Ionic,我有一些路线定义如下: $stateProvider .state('app', { url: '/', abstract: true, views: { 'menuContent': { templateUrl: 'templates/home.html'

我有一些路线定义如下:

$stateProvider
            .state('app', {
                url: '/',
                abstract: true,
                views: {
                    'menuContent': {
                        templateUrl: 'templates/home.html'
                    }
                }
            })
            .state('app.restricted', {
                url: '/restricted',
                views: {
                    'content': {
                        templateUrl: 'templates/restricted/restricted-dashboard.html',
                        controller: 'RestrictedController as vmRestricted'
                    }
                },
                resolve: {
                    isGranted: 'isGranted'
                }
            })
            .state('app.restricted.pending', {
                url: '/pending',
                views: {
                    'tabsView': {
                        templateUrl: 'templates/restricted/restricted-manage-pending.html',
                        controller: 'RestrictedPendingController as vm'
                    }
                },
                resolve: {
                    isGranted: 'isGranted'
                }
            })
            .state('app.restricted.devices', {
                url: '/devices',
                views: {
                    'tabsView': {
                        templateUrl: 'templates/trusted/restricted-manage-devices.html',
                        controller: 'RestrictedDevicesController as vm'
                    }
                },
                resolve: {
                    isGranted: 'isGranted'
                }
            })
            .state('app.grant', {
                url: '/grant-access',
                views: {
                    'content': {
                        templateUrl: 'templates/grant-access.html',
                        controller: 'GrantAccessController as vm'
                    }
                }
            })
        ;
在这些路线中,我有一个限制区和一个授权访问页面来授权访问限制区。 当
isgrant
解析提供程序被拒绝时,我重定向到
app.grant
路由

这是执行此操作的代码:

$rootScope.$on(AngularEvents.STATE_CHANGE_ERROR, _onStateChangeError);

function _onStateChangeError(event, toState, toParams, fromState, fromParams, error){

            switch (error) {

                case 'accessRejected':
                    $state.go('app.grant');
                    break;

            }

        }
以下是我的
isgrated
提供商的代码:

(function() {

    'use strict';

    angular.module('app')
        .provider('isGranted', isGrantedProvider);

    isGrantedProvider.$inject = [];

    function isGrantedProvider() {

        this.$get = isGranted;

        isGranted.$inject = ['$q', '$log', 'grantService'];

        function isGranted($q, $log, grantService){
            $log.log('isGrantedProvider');

            if (grantService.isGranted()) {
                return $q.when(true);
            } else {
                return $q.reject('accessRejected');
            }
        }

    }

})();
grantService.isgrant()
只返回一个布尔值)

第一次使用
$state.go('app.restricted')
进入
app.restricted
路径时,将执行提供程序。 该路由被拒绝,因为未授予访问权限,我们被重定向到
app.grant
路由

在此页面中,用户可以登录并访问限制区域。用户登录后,我们将其重定向到
app.restricted.pending
路由,但未调用解析,路由被拒绝,我们再次重定向到
app.grant
路由,而访问被授予

为什么不叫决心? 有办法强迫它吗

编辑

经过一些测试,我有了新的信息

我看到resolve只有在作为服务时才被第二次调用:

当我们进入以下状态时,始终执行此解析:

state('app.restricted', {
                url: '/restricted',
                views: {
                    'content': {
                        templateUrl: 'templates/restricted/restricted-dashboard.html',
                        controller: 'RestrictedController as vmRestricted'
                    }
                },
                resolve: {
                    isGranted: ['$log', function($log) {
                        $log.log('RESOLVE');
                    }]
                }
            })
state('app.restricted', {
                    url: '/restricted',
                    views: {
                        'content': {
                            templateUrl: 'templates/restricted/restricted-dashboard.html',
                            controller: 'RestrictedController as vmRestricted'
                        }
                    },
                    resolve: {
                        isGranted: 'isGranted'
                    }
                })

angular.module('app')
        .provider('isGranted', isGrantedP);

    isGrantedP.$inject = [];

    function isGrantedP() {

        this.$get = isGranted;

        isGranted.$inject = ['$q', '$log'];

        function isGranted($q, $log){
            $log.log('RESOLVE');
        }

    }
但是,即使我再次进入状态,此解析也只执行一次:

state('app.restricted', {
                url: '/restricted',
                views: {
                    'content': {
                        templateUrl: 'templates/restricted/restricted-dashboard.html',
                        controller: 'RestrictedController as vmRestricted'
                    }
                },
                resolve: {
                    isGranted: ['$log', function($log) {
                        $log.log('RESOLVE');
                    }]
                }
            })
state('app.restricted', {
                    url: '/restricted',
                    views: {
                        'content': {
                            templateUrl: 'templates/restricted/restricted-dashboard.html',
                            controller: 'RestrictedController as vmRestricted'
                        }
                    },
                    resolve: {
                        isGranted: 'isGranted'
                    }
                })

angular.module('app')
        .provider('isGranted', isGrantedP);

    isGrantedP.$inject = [];

    function isGrantedP() {

        this.$get = isGranted;

        isGranted.$inject = ['$q', '$log'];

        function isGranted($q, $log){
            $log.log('RESOLVE');
        }

    }

为什么不每次都调用此服务?是因为服务是单体的吗?我应该如何继续?

经过大量的调查和测试,我找到了解决方案

首先,让我们看看它为什么不起作用

正如文档(.$stateProvider)中提到的,如果解析是一个字符串,那么它对应于一个服务

工厂-{string | function}:如果是string,则它是服务的别名。 否则,如果是函数,则注入该函数并返回它所处理的值 附属国。若结果是一个承诺,那个么在确定其价值之前就已经解决了 注入控制器

正如angularjs文档()中提到的,所有服务都是单例的,这意味着它将只实例化一次

注:Angular中的所有服务均为单例服务。这意味着 injector最多使用每个配方一次来创建对象。这个 然后,injector缓存参考,以备将来需要

为什么它很重要?

因为解析不会在我们的服务中调用函数。它们只使用实例化服务的返回值但是因为我们的服务只实例化一次,所以返回值总是相同的!(因为我们的服务初始化只调用一次)

我们能做什么?

从我的测试中,我可以看到如下定义的解决方案:

resolve: {
                    myResolve: ['$log', function($log) {
                        $log.log('My Resolve!');
                    }]
                }
resolve: {
                        myResolve: ['myResolveService', function(MyResolveService) {
                            myResolveService.log();
                        }]
                    }
angular.module('app')
        .factory('myResolve', myResolve);

    myResolve.$inject = ['$log'];

    function myResolve($log) {

        function service(){
            this.log = log;

            function log() {
                $log.log('My resolve!');
            }
        }

        return new service();

    }
始终执行,因此我们可以通过这种方式编写它们以使其正确工作

但是如果我想使用我的服务,我该怎么办?

我发现,能够使用我的服务并具有类似于以下语法的最佳工作解决方案:
myResolve:“myResolveService”
是这样声明我的解析:

resolve: {
                    myResolve: ['$log', function($log) {
                        $log.log('My Resolve!');
                    }]
                }
resolve: {
                        myResolve: ['myResolveService', function(MyResolveService) {
                            myResolveService.log();
                        }]
                    }
angular.module('app')
        .factory('myResolve', myResolve);

    myResolve.$inject = ['$log'];

    function myResolve($log) {

        function service(){
            this.log = log;

            function log() {
                $log.log('My resolve!');
            }
        }

        return new service();

    }
我的服务是这样的:

resolve: {
                    myResolve: ['$log', function($log) {
                        $log.log('My Resolve!');
                    }]
                }
resolve: {
                        myResolve: ['myResolveService', function(MyResolveService) {
                            myResolveService.log();
                        }]
                    }
angular.module('app')
        .factory('myResolve', myResolve);

    myResolve.$inject = ['$log'];

    function myResolve($log) {

        function service(){
            this.log = log;

            function log() {
                $log.log('My resolve!');
            }
        }

        return new service();

    }
此代码也可适用于返回承诺的解析:

决心:

resolve: {
                            myResolve: ['myResolveService', function(MyResolveService) {
                                return myResolveService.check();
                            }]
                        }
服务:

angular.module('app')
        .factory('myResolve', myResolve);

    myResolve.$inject = ['$q', 'myService'];

    function myResolve($q, myService) {

        function service(){

            this.check = check;

            function check() {
                var defer = $q.defer();

                if (myService.check()) {
                    defer.resolve(true);
                } else {
                    defer.reject('rejected');
                }

                return defer.promise;
            }
        }

        return new service();

    }

确定没有调用解析还是grantService返回了错误的值?@AurélienThieriot我确定没有调用解析,因为提供程序中的$log没有显示出来。不错!