Angular ui-router $state.go не перенаправляет внутри решение
В моем приложении angularjs я проверяю, попадает ли пользователь на целевую страницу и уже аутентифицирован, а затем перенаправляет его на домашнюю страницу.
.state('landingpage', {
abstract: "true",
url: "/landingpage",
templateUrl: "app/landingpage/landingpage.html",
resolve: {
AutoLoginCheck: ['$state', '$window', function ($state, $window) {
if($window.localStorage.access_token != null)
{
if($window.sessionStorage.access_token == null) {
$window.sessionStorage.access_token = $window.localStorage.access_token;
}
UserInfoService.SetUserAuthenticated(true);
// it is not redirecting
return $state.go('app.home');
}
}]
}
})
Проблема в том, что, хотя весь код решения успешно запущен, пользователь не перенаправляется на app.home. Может кто-нибудь сказать, почему это происходит?
Примечание. В "приложении" состояния также есть решение, в котором он извлекает данные, которые будут отображаться в состоянии "app.home".
Ответы
Ответ 1
В вашей проблеме может быть два решения.
-
Во-первых, вы можете испускать событие, и слушатель будет обрабатывать ваш переход состояния. Вы можете реализовать слушателя в любом месте родительского контроллера.
-
Во-вторых, вы можете реализовать крюк $stateChangeStart и проверить состояние переадресации там
$rootScope.$on('$stateChangeStart', function (event, toState) {
if (toState.name === 'landingpage') {
if (!isAuthenticated()) { // Check if user allowed to transition
event.preventDefault(); // Prevent migration to default state
$state.go('home.dashboard');
}
}
});
Ответ 2
.state('landingpage', {
abstract: "true",
url: "/landingpage",
templateUrl: "app/landingpage/landingpage.html",
resolve: {
AutoLoginCheck: ['$state','$window', '$q','$timeout', function ($state, $window,$q,$timeout) {
if($window.localStorage.access_token != null)
{
if($window.sessionStorage.access_token == null) {
$window.sessionStorage.access_token = $window.localStorage.access_token;
}
UserInfoService.SetUserAuthenticated(true);
$timeout(function() {
$state.go('app.home')
},0);
return $q.reject()
}
}]
}
})
Это сработает для вас.
Ответ 3
Вместо этого вы можете использовать $location.url('/')
.
Ответ 4
Вы можете использовать решение, чтобы предоставить вашему контроллеру контент или данные, которые являются обычными для состояния. Решение - это необязательная карта зависимостей, которая должна быть введена в контроллер.
У вас может быть контроллер, который проверяет AuthState и соответствующим образом перенаправляет.
.state('landingpage', {
abstract: "true",
url: "/landingpage",
templateUrl: "app/landingpage/landingpage.html",
resolve: {
AutoLoginCheck: ['$window', function ($window) {
if($window.localStorage.access_token != null)
{
if($window.sessionStorage.access_token == null) {
$window.sessionStorage.access_token = $window.localStorage.access_token;
}
//assuming userInfoService does the authentication
var isAuthenticated = userInfoService.SetUserAuthenticated(true);
return isAuthenticated;
}
}]
},
controller: ['$state','AutoLoginCheck', function($state, AutoLoginCheck){
if(AutoLoginCheck){
//authenticated
$state.go('app.home');
} else {
//redirect to unauthenticated page
$state.go('....');
}
}]
})
Ответ 5
Это старый поток, но я использую $location.path() для выполнения перенаправления внутри блока state.resolve()
Ответ 6
В любом случае решите ожидание состояния обещания. Самое лучшее, что вы можете сделать, это вернуть обещание и добавить тайм-аут для вашего состояния:
resolve: {
AutoLoginCheck: ['$state', '$window', '$timeout', '$q', function ($state, $window, $timeout, $q) {
var deferred = $q.defer();
if(user.isLogin()){
deferred.resolve();
}else{
$timeout(function(){
$state.go('app.home');
}
deferred.reject();
}
return deferred.promise;
}]