当前位置: 首页 > 面试题库 >

解决不第二次

呼延承平
2023-03-14
问题内容

我有一些这样定义的路线:

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

在这些路线中,我有一个禁区和一个授予访问权页面以授予对该禁区的访问权限。当isGranted解析提供者被拒绝时,我将重定向到该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;

            }

        }

这是我的isGranted提供者的代码:

(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.isGranted()只返回一个布尔值)

我第一次app.restricted$state.go('app.restricted')提供者一起去路线被执行。该路由被拒绝,因为未授予访问权限,我们被重定向到该app.grant路由。

在此页面中,用户可以登录并有权访问限制区域。一旦用户登录,我们会将其重定向到该app.restricted.pending路由,但不会调用解决方法,并且该路由将被拒绝,并且我们将app.grant再次重定向到该路由,而访问被授予。

为什么不叫解决方案?有办法强迫它吗?

编辑

经过测试,我有新信息。

我看到只有在将解决方案作为服务时才第二次调用它:

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

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');
        }

    }

为什么每次都不调用此服务?是因为服务是单例吗?我应该如何进行?


问题答案:

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

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

如文档中所述(http://angular-ui.github.io/ui-
router/site/#/api/ui.router.state。$
stateProvider),如果解析为字符串,则对应于服务

factory-{string |
function}:如果为string,则为服务的别名。否则如果是函数,则将其注入并返回将其视为依赖项的值。如果结果是一个承诺,则在将其值注入控制器之前对其进行解析。

正如angularjs
docs(https://docs.angularjs.org/guide/providers)所述,所有服务都是单例,这意味着它将仅实例化一次

注意:Angular中的所有服务都是单例。这意味着注入器最多使用每个配方一次来创建对象。然后,注入器将参考保存为将来的所有需求。

它为什么如此重要?

因为解析不调用我们服务内部的函数。他们只使用实例化服务的返回值。 但是
因为我们的服务只会实例化一次,所以返回值将始终相同!(因为我们的服务初始化仅被调用一次)

我们可以做什么?

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

resolve: {
                    myResolve: ['$log', function($log) {
                        $log.log('My Resolve!');
                    }]
                }

总是执行,因此我们可以用这种方式编写它们以使其正常工作。

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

我发现能够使用我的服务并且具有类似于以下语法的最佳工作解决方案:myResolve: 'myResolveService'声明我的决心如下:

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();

    }


 类似资料:
  • 性能分析图中如果设置双x轴,第二个label无论如何也显示不出来,只能看到轴线,请问应该如何更改以显示出图标上方x轴的label

  • 本文向大家介绍解决JQuery全选/反选第二次失效的问题,包括了解决JQuery全选/反选第二次失效的问题的使用技巧和注意事项,需要的朋友参考一下 最近在项目中,遇到一个问题,测试全选/反选功能时,第一次对母框进行选中/非选中时,能同步子框的全选/反选状态,之后再点击母框,子框就没反应了。 原代码大致结构关键如下: 步骤一:尝试正面刚一波: 卒-----完全没有效果,弃之。 步骤二:快速上网搜索一

  • 本文向大家介绍jquery操作checkbox火狐下第二次无法勾选的解决方法,包括了jquery操作checkbox火狐下第二次无法勾选的解决方法的使用技巧和注意事项,需要的朋友参考一下 最近在学习jQuery(版本jquery-1.9.1.js),要求用jQuery实现全选/全不选、反选,在IE(IE8)中没有问题,但在火狐浏览器中调试的时候出现了一些小问题,达不到效果。 html代码如下: j

  • 从一段时间以来,我开始有以下问题。我播放它通过加载文件并显示图像的级别。我完成了关卡,它就会卸载文件。当我再次玩关卡时,它只显示堡垒,玩家,敌人,子弹,但它不再显示其他的图像,如地面,背景,树木等,而是显示给我白色的素色。 然而,就在此时,我没有从AssetManager获取纹理,而是将所有内容改为创建新对象,如,它不会产生此错误。我猜是有什么地方不对或遗漏了。 它实际上只是白色的,但当我创建地面

  • 在插入新记录之前,我正在验证记录的存在性。但是,代码不会跳入insert块。在Reader.Close之后跳转到finally block 我怀疑我一定是做错了什么,因为没有例外,而且每次RecordsInfacted=-1

  • 以下是对不熟悉此问题的人的问题声明: 给定一个二维板和一个单词,找出这个单词是否存在于网格中。这个词可以由顺序相邻单元格的字母构成,其中“相邻”单元格是那些水平或垂直相邻的单元格。同一个字母单元格不能使用不止一次。 解决方案2 现在,据我所知,随着Java的短路,的两个版本都应该停止探索其他路径,如果任何子问题返回true。事实上,我可以评估的两个版本之间唯一的操作差异是,如果找到解决方案,第一个