在ui-router上更改状态时出现angularjs infdig错误(带视频)

Posted

技术标签:

【中文标题】在ui-router上更改状态时出现angularjs infdig错误(带视频)【英文标题】:angularjs infdig error when change state on ui-router(with video) 【发布时间】:2016-06-08 21:19:33 【问题描述】:

新编辑: 检查登录的身份验证服务

'use strict';

angular.module('MainApp.login.services', [])
    .factory('authService', ['AUTH_ENDPOINT', 'LOGOUT_ENDPOINT', '$http', '$cookieStore', function (AUTH_ENDPOINT, LOGOUT_ENDPOINT, $http, $cookieStore) 
        var auth = ;
        auth.login = function (username, password) 
            return $http.post(AUTH_ENDPOINT, username: username, password: password)
                .then(function (response, status) 
                    auth.user = response.data;
                    $cookieStore.put('user', auth.user);
                    return auth.user;
                );
        ;
        auth.logout = function () 
            return $http.post(LOGOUT_ENDPOINT).then(function (response) 
                auth.user = undefined;
                $cookieStore.remove('user');
                $cookieStore.remove('event');
            );
        ;
        return auth;
    ])
    .value('AUTH_ENDPOINT', 'http://www.mydomain.gr/assets/modules/login/dal/login.php')
    .value('LOGOUT_ENDPOINT', 'http://www.mydomain.gr/assets/modules/login/dal/logout.php');  

更新: 不幸的是,这是整个网络应用程序的一部分,所以我无法将它上传到 jsfiddle。我制作了一个 youtube 视频,在其中我在调试应用程序时准确显示了错误。从 1:30 开始问题。请随意查看视频 下面是我的 Angular 应用程序的 app.js

我在模板中的 $watch(es) 会不会造成错误?

Youtube,1:30 后开始报错:https://www.youtube.com/watch?v=3Cc2--BkdQ4&feature=youtu.be

首次加载网站时,登录屏幕会加载并要求提供凭据。

如果用户登录它会重定向到第 4 部分页面(从登录控制器内部),到目前为止一切顺利!

问题是每当我在浏览器上打开一个新标签时,尝试加载网站:

    应该看到用户已经登录并在part4页面重定向他。

    而不是这个,正如我在浏览器的调试中看到的那样,它转到了 resolve:login

    然后它上升到$rootScope.$on('$stateChangeError',go.state(part4)

    然后进入第4部分的解析,然后进入登录的解析,再次进入$statechangeerror函数

5.最后我得到了错误:Error: [$rootScope:infdig] http://errors.angularjs.org/1.4.8/$rootScope/infdig?p0=10&p1=%5B%5D 但奇怪的是它最终重定向到了第 4 部分页面,但是出现了那个错误!!

谁能帮帮我。

'use strict';

var app = angular.module('MainApp', ['mApp',
    'MainApp.loginModule',
    'MainApp.part4Module',
    'MainApp.part5Module',
    'MainApp.eventModule',
    'ui.router', 'ui.router.tabs', 'ngCookies']);

angular.module('MainApp')
    .run(['$rootScope', '$state', '$cookieStore', 'authService', function ($rootScope, $state, $cookieStore, authService) 
        $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) 
            if (error.unAuthorized) 
                $state.go('login');
            
            else if (error.authorized) 
                $state.go('part4');
            
        );

        authService.user = $cookieStore.get('user');
    ])
    .config(function ($stateProvider, $urlRouterProvider, $locationProvider)  //$stateProvider & $urlRouterProvider are from ui.router module
        $stateProvider
            .state('floorplan', 
                url: '/floorplan/:activeEventId/:activeHallId/:activeHallVariant',
                controller: 'ParticipantsCtrl',
                templateUrl: '/assets/modules/part1/part1.html',
                resolve: 
                    user: ['authService', '$q', function (authService, $q) 
                        return authService.user || $q.reject(unAuthorized: true);
                    ]
                
            )
            .state('event', 
                url: '/event/:activeEventId',
                templateUrl: 'assets/modules/event/eventPartial.html',
                controller: 'eventctrl',
                resolve: 
                    user: ['authService', '$q', function (authService, $q) 
                        return authService.user || $q.reject(unAuthorized: true);
                    ]
                
            )
            .state('part4', 
                url: '/part4',
                resolve: 
                    user: ['authService', '$q', function (authService, $q) 
                        return authService.user || $q.reject(unAuthorized: true);
                    ]
                ,
                controller: 'part4ctrl',
                templateUrl: '/assets/modules/part4/part4Partial.html'
            )
            .state('login', 
                url: '/login',
                controller: 'LoginCtrl',
                templateUrl: '/assets/modules/login/login.html',
                resolve: 
                    user: ['authService', '$q', function (authService, $q) 
                        if (authService.user)    
                         return $q.reject(authorized: true);
                        
                    ]
                
            );
        $urlRouterProvider.otherwise('login');
    );

我在 youtube 上上传了一个视频,描述并显示了错误: 优酷:https://www.youtube.com/watch?v=3Cc2--BkdQ4&feature=youtu.be

【问题讨论】:

我对你的app.js 有点困惑。我很确定应该是app.run... 而不是angular.module('MainApp').run @LJ.Wizard 使用angular.module('MainApp') 是更好的做法。不依赖于设置全局变量 在不知道授权如何工作的情况下很难提供帮助 @charlietfl 我明白了。谢谢。 你让自己陷入了一个无限循环。当你被路由到 part4 状态时,你能得到一个error.authorized 吗? 【参考方案1】:

你可以试试这个倒置的吗?

.run(['$rootScope', '$state', '$cookieStore', 'authService', function ($rootScope, $state, $cookieStore, authService) 
    $rootScope.$on('$stateChangeStart', function (...) 
    authService.user = $cookieStore.get('user');
                if (authService.user) 
                    $state.go('part4');
                
                else if (!authService.user) 
                    $state.go('login');
                
            );

这将在每个路由声明中的解析中跳过到 $q 的往返。其次,这也将解决您/r 在每条路线的解析范围内一直检查用户的问题。在 .config() 中设置 authService.user = $cookieStore.get('user'); 某处。应该可以解决您的问题。

【讨论】:

这是 $stateChangeError 而不是 $stateChangeStart,否则他的导航会在第 4 部分以外的其他页面上出现问题并登录:P 是的,我希望 @theo-itzaris 使用 $stateChangeStart 来处理身份验证和 url 更改,并在配置中初始化 authService.user = $cookieStore.get('user');。我正在接近相反的方向。 $q 在这里是不必要的。【参考方案2】:

我认为首先解决状态是因为您在 app.run 中注入了 $state。

这导致尝试使用未定义的用户解析第 4 部分状态的解析,然后引发事件并将在下一个摘要循环中解析,因此在您重定向到登录页面之前初始化使用,这会将您重定向到第四部分。

尝试在两个 angular.run 中分开,第一个将运行 authService 的 init 而不注入 $state。第二个将注入 $state 以初始化 $stateCHangeError 侦听器(仅在第二个之前定义第一个)。

如果这还不够:拆分您的模块:在模块“A”中包含 authService 的模块具有专用的 angular.module('A').run,模块“B”中的第二个模块具有对“的依赖” A' 与 $stateChangeError 的 angular.module('B').run

【讨论】:

【参考方案3】:

一切似乎都很好。

经过几个小时和许多断点后,我意识到问题不是由任何$watch() 引起的,我的控制器上有很多$watch

这只是一个状态问题,正如您在我的问题中看到的那样,我没有 '/' 状态,这导致了无限循环,因为:

    当我删除 url 的扩展部分时,我有:www.mydomain.com/,然后$stateProvider 搜索我可用的 'states' 但找不到 '/' 状态,所以它重定向到“登录”状态。 进入“登录”状态,我检查是否 user==true 并拒绝错误。 然后,$rootScope.$on('$stateChangeError').. 执行并且我调用 state.go('part4') ,它解析状态 'part4' 并再次进入状态 'login' 解析,并再次相同,直到达到 $digest 循环的最大允许迭代次数。

我是怎么解决的

我不知道这是否是最好的方法,但我在 app.js 上添加了一个“/”状态,它按预期工作:

.state('/', 
                url: '/',
                controller: 'LoginCtrl',
                templateUrl: '/assets/modules/login/login.html',
                resolve: 
                    user: ['authService', '$q', function (authService, $q) 
                        if (authService.user) 
                            return $q.reject(authorized: true, user: authService.user);
                        
                    ]
                
            );

【讨论】:

以上是关于在ui-router上更改状态时出现angularjs infdig错误(带视频)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Angular ui-router 设置 URL 查询参数而不改变状态

通过 express、mongoose 和 angular 删除 mongo 文档时出现 404

当 UI-Router ES6 中的状态更改时,$stateChangeStart 不会被触发?

带有模型数据的 Ui-Router

Angular - ui-router 获取先前的状态

Angular 2、TypeScript 和 ui-router - 如何获取状态参数