Angularjs infdig error при изменении состояния на ui-router (с видео)

Новое редактирование: authservice, который проверяет логин:

'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 начинается проблема. Не стесняйтесь изучать видео/ ниже app.js моего приложения angular.

Могут ли $watch (ы), которые у меня есть в шаблонах, создать ошибку?

Youtube, после 1:30 запускается ошибка: https://www.youtube.com/watch?v=3Cc2--BkdQ4&feature=youtu.be

При первой загрузке сайта экран входа в систему загружается и запрашивает учетные данные.

Если вход в систему пользователя перенаправляется на страницу part4 (изнутри контроллера входа), пока это так хорошо!

Проблема заключается в том, что когда я открываю новую вкладку в браузере, попробуйте загрузить веб-сайт:

  • Он должен видеть, что пользователь уже зарегистрирован и перенаправляет его на страницу part4.

  • вместо этого, как я вижу при отладке браузера, он переходит к решению: login

  • Затем он поднимается внутрь $rootScope.$on('$stateChangeError', и до go.state(part4)

  • Затем он переходит к решению part4, а затем переходит к разрешению входа и снова в функцию $statechangeerror

5. И наконец, я получаю ошибку: Error: [$rootScope:infdig] http://errors.angularjs.org/1.4.8/$rootScope/infdig?p0=10&p1=%5B%5D но странно, что он, наконец, перенаправляется на страницу part4, но с этой ошибкой!

Кто-нибудь может мне помочь.

'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, описывая и показывая ошибку: youtube: https://www.youtube.com/watch?v=3Cc2--BkdQ4&feature=youtu.be

Ответ 1

Все выглядит нормально.

После многих часов и многих точек останова я понял, что проблема не вызвана каким-либо $watch(), у меня есть много $watch на моих контроллерах.

Это просто проблема состояния, как вы можете видеть по моему вопросу, у меня не было состояния '/', и это вызвало бесконечный цикл, потому что:

  • когда я удаляю часть расширения URL-адреса, у меня есть: www.mydomain.com/, затем $stateProvider выполняет поиск доступных состояний, но не может найти состояние "/", поэтому он перенаправляется в состояние входа в систему.
  • В состояние "login" я проверяю, является ли 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});
                        }
                    }]
                }
            });

Ответ 2

Я думаю, что состояние разрешено первым, потому что вы вводите $state в свой app.run.

Что приводит к попытке решить разрешение состояния part4 с помощью пользователя undefined, тогда событие будет выбрано и будет разрешено в следующем цикле цикла, поэтому использование будет инициализировано до того, как вы получите redirecit на страницу входа в систему, которая будет перенаправлена вы к part4.

Попробуйте разделиться на два angular.run, 1-й, который запустит init authService без ввода int $state. Второй, который будет вводить $state, чтобы запустить слушатель $stateCHangeError (просто определяя 1-й до 2-го).

Если этого недостаточно: разделите свой модуль: тот, который содержит authService в модуле "A", с выделенным angular.module( "A" ). 2-й в модуле "B" с зависимостью к 'A' с модулем angular ('B'). Запустите для $stateChangeError

Ответ 3

Вы можете попробовать это перевернутое?

.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'); где-нибудь. Должен решить вашу проблему.