Сервисное внедрение angularJS в блок запуска
У меня есть приложение Angular (1.5) со службой аутентификации (см. Ниже), которую я создал.
(function () {
"use strict";
angular
.module("app.core")
.service("mfAuth", mfAuth);
/** @ngInject */
function mfAuth(api, $rootScope, AUTH_EVENTS, $cookies) {
var currentUser = { userName: "" };
getSession();
var setRememberMe = function (rememberme, userId) {
if (rememberme && userId && userId > 0) {
var date = new Date();
date.setDate(date.getDate() + 30);
$cookies.put('remember_me', userId, { expires: date });
} else
$cookies.remove('remember_me');
};
function changeUser(user) {
var userProps = {
displayName: user.displayName,
...
};
angular.extend(currentUser, userProps);
}
function isLoggedIn(user) {
if (user === undefined) {
user = currentUser;
}
return user && user.userId > 0;
};
function getSession(force) {
var rememberme = $cookies.get('remember_me') !== undefined;
if (rememberme || force) {
var apiAuth = new api.Auth();
apiAuth.$getSession(
null,
function(response) {
if (response.result !== undefined) {
changeUser(response.result);
$rootScope.$broadcast(AUTH_EVENTS.isAuthenticated);
} else {
changeUser({});
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
},
function(response) {
changeUser({});
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
);
} else {
changeUser({});
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
};
function login(user, successCallback, errorCallback) {
var apiAuth = new api.Auth();
apiAuth.userName = user.userName;
apiAuth.password = user.password;
apiAuth.$login(
null,
function (response) {
getSession(true);
if (successCallback)
successCallback(response);
setRememberMe(user.rememberme, response.userId);
},
function (response) {
if (errorCallback)
errorCallback(response);
}
);
};
function logout(successCallback, errorCallback) {
var apiAuth = new api.Auth();
apiAuth.$logout(
null,
function (response) {
changeUser({});
if (successCallback)
successCallback();
setRememberMe(false, null);
$rootScope.$broadcast(AUTH_EVENTS.logoutSuccess);
},
function (response) {
if (errorCallback)
errorCallback(response);
}
);
}
return {
isLoggedIn: isLoggedIn,
login: login,
logout: logout,
user: currentUser
};
}
}());
Я слушаю трансляции на моем главном RunBlock, как это...
(function () {
'use strict';
angular
.module('app.core')
.run(runBlock);
/** @ngInject */
function runBlock(msUtils, fuseGenerator, fuseConfig, $rootScope, AUTH_EVENTS, $state) {
$rootScope.$on(AUTH_EVENTS.notAuthenticated, function (ev, reason) {
if (!$state.is('app.auth_login')) {
event.preventDefault();
$state.go('app.auth_login');
}
});
$rootScope.$on(AUTH_EVENTS.isAuthenticated, function (ev, reason) {
if ($state.is('app.auth_login')) {
event.preventDefault();
$state.go('app.dashboard');
}
});
$rootScope.$on(AUTH_EVENTS.logoutSuccess, function (ev, reason) {
if (!$state.is('app.auth_login')) {
event.preventDefault();
$state.go('app.auth_login');
}
});
}
})();
Когда служба внедряется в контроллер входа, все работает как положено - создается экземпляр службы, и запускается функция getSession(), и приложение определяет, требует ли пользователь аутентификации или нет.
Моя проблема в том, что мне нужно иметь доступ к сервису из блока run для некоторых функций авторизации, и как только я внедряю сервис mfAuth в мою функцию runBlock, я обнаруживаю, что AUTH_EVENTS.notAuthenticated определяется правильно, но метод $state.go не работает, и пользователь не перенаправлен в состояние входа в систему.
Я читал вокруг и не могу найти подсказки относительно проблемы. Я попытался прослушать событие $stateChangeError пользовательского маршрутизатора, и оно не запускается. У меня нет идей, поэтому я решил превратить стек в переполнение. Я пытался найти похожие вопросы о переполнении стека, и я уверен, что ответ уже будет здесь, но я изо всех сил пытаюсь найти правильные ключевые слова, чтобы найти проблему.
Кто-нибудь может помочь?
ОБНОВЛЕНИЕ Я только что добавил следующую запись в журнал $stateChangeStart...
$rootScope.$on('$stateChangeStart',
function (event, toState, toParams, fromState, fromParams) {
console.log("event: ", event);
console.log("toState: ", toState);
console.log("toParams: ", toParams);
console.log("fromState: ", fromState);
console.log("fromParams: ", fromParams);
});
Это производит следующий вывод консоли
event: Object {name: "$stateChangeStart", targetScope: Scope, defaultPrevented: false, currentScope: Scope} core.run.js:63
toState: Object {url: "/auth/login", views: Object, bodyClass: "login", name: "app.auth_login"} core.run.js:64
toParams: Object {} core.run.js:65
fromState: Object {name: "", url: "^", views: null, abstract: true} core.run.js:66
fromParams: Object {} core.run.js:62
event: Object {name: "$stateChangeStart", targetScope: Scope, defaultPrevented: false, currentScope: Scope} core.run.js:63
toState: Object {url: "/dashboard", views: Object, resolve: Object, name: "app.dashboard"} core.run.js:64
toParams: Object {} core.run.js:65
fromState: Object {name: "", url: "^", views: null, abstract: true} core.run.js:66
fromParams: Object {}
Таким образом, проблема заключается в том, что сервис getSession запускается и запрашивает переход к состоянию входа в систему ДО чего-либо еще, например ($urlRouterProvider.otherwise и URL-адрес, введенный в адресную строку браузера).