I'm trying to introduce login into the way the user navigates accross the application.
我正在尝试将登录引入用户在应用程序中导航的方式。
I pretend to redirect the user to the page were he was before he navigate to the login page if that page meets specific requirements
如果该页面满足特定要求,我假装将用户重定向到他导航到登录页面之前的页面
Preventing the event from the $stateChangeStart stop's the state change like expected but when i run the $state.go('into_somewhere') i enter an infinit loop
防止来自$ stateChangeStart的事件停止状态改变就像预期的那样,但当我运行$ state.go('into_somewhere')时,我进入一个无限循环
My angular version is 1.3.1 and the ui-router is the latest
我的角度版本是1.3.1,ui-router是最新版本
.factory('RouteHistory', function ($rootScope,$log, $state, Auth, $urlRouter, $timeout) {
// after the user enter a page
var currentState = '';
// when the user is trying to access a page that he has not permissions
// or that requires the user to be logged in
var pendingState = '';
var isMenuTogglerVisible = false;
var skipFromStateVal = true;
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
event.preventDefault();
if (toState.name == 'login' && fromState.name != 'login'){
$log.log('Ui-router: changing to login');
// $urlRouter.sync();
$state.go('login')
//pendingState = fromState;
//$log.log('Peding state updated to:' + pendingState.name );
//$urlRouter.sync();
}
if (fromState.name == 'login' && Auth.isLoggedIn()) {
$log.log('Ui-router: going from login');
//$state.go(fromState.name);
$timeout(function(){
// $state.go('home', null, {/*reload: true, location: 'replace'*/});
$state.go('browse-machine');
//$urlRouter.sync();
},2000)
}
$log.log({
'toState': toState,
'toParams': toParams,
'fromState': fromState,
'fromParams': fromParams
})
})
return {
};
});
6 个解决方案
#1
11
In general I would say, let's redirect ($state.go()
) only if needed. In other cases, get out from the event listener:
一般来说,我会说,只有在需要时才重定向($ state.go())。在其他情况下,从事件监听器中退出:
if (toState.name === 'login' ){
// doe she/he try to go to login? - let him/her go
return;
}
if(Auth.isLoggedIn()){
// is logged in? - can go anyhwere
return;
}
// else
$state.go('login')
This is simplified logic, but shows, that we should change to execution only if needed. There are some other examles with more detailed implementation and plunkers:
这是简化的逻辑,但表明我们应该只在需要时改为执行。还有一些其他考试有更详细的实施和掠夺者:
- Confusing $locationChangeSuccess and $stateChangeStart
- 困惑$ locationChangeSuccess和$ stateChangeStart
- Angular UI Router: nested states for home to differentiate logged in and logged out
- Angular UI Router:家庭的嵌套状态,用于区分登录和注销
- other example of log in
- 其他登录示例
- angular ui-router login authentication
- angular ui-router登录验证
As provided in the comment, there was plunker, which I changed like this here
正如评论中所提到的,有一个plunker,我在这里改变了
...
// three new lines
if (toState.name === 'specialRoute'){
return;
}
if (fromState.name=='route1'){
event.preventDefault();
$state.go('specialRoute')
}
And this is not looping anymore. Please, check it here
这不再循环了。请在这里查看
#2
5
This answer helped me:
这个答案帮助了我:
$urlRouterProvider.otherwise( function($injector, $location) {
var $state = $injector.get("$state");
$state.go("app.home");
});
Original: Why does AngularJS with ui-router keep firing the $stateChangeStart event?
原文:为什么带有ui-router的AngularJS会继续触发$ stateChangeStart事件?
#3
5
You should use the notify option :
您应该使用notify选项:
$state.go('your.state',{ your params },{notify: false});
This will prevent stateChangeStart to fire again.
这将阻止stateChangeStart再次触发。
#4
0
I simply used $location.path('every/where')
instead of $state.go('every/where')
我只是使用$ location.path('every / where')而不是$ state.go('every / where')
:) .
:)。
#5
0
The infinite loop is partly caused by
无限循环部分是由于
if (toState.name == 'login' ...) { $state.go('login'); ...
..which says if
you're going to the login state, then
go to the login state.
..如果你要进入登录状态,那么就进入登录状态。
...And calling event.preventDefault()
as the first line in the event handler doesn't help. When you use go()
to go to the login screen (or anywhere else), that state change is also prevented by event.preventDefault()
. It should only be used within an if
.
...并且调用event.preventDefault()作为事件处理程序中的第一行没有帮助。当您使用go()转到登录屏幕(或其他任何地方)时,event.preventDefault()也会阻止该状态更改。它应该只在if中使用。
Your entire $stateChangeStart handler should instead be...
你的整个$ stateChangeStart处理程序应该是......
if (!Auth.isLoggedIn() && toState.name != 'login') {
event.preventDefault();
Auth.desiredState = toState.name;
$state.go('login');
}
...which reads naturally. "If
you're not logged in and you're not already going to the login screen, then
stop what you're doing, I'll remember where you wanted to go, and you now go to the login screen."
......自然地读。 “如果你没有登录,而你还没有进入登录界面,那么就停止你正在做的事情,我会记住你想去的地方,现在就进入登录界面。”
Later your Auth
object will issue a $state.go(Auth.desiredState)
when it's satisfied with the user.
稍后,当用户满意时,您的Auth对象将发出$ state.go(Auth.desiredState)。
#6
0
It works for me, Below code helps to get rid of infinite loop
它适用于我,下面的代码有助于摆脱无限循环
let firstPass = true;
$scope.$on('$stateChangeStart', function(event, toState, toParams) {
if ($scope.addForm.$dirty && firstPass) {
event.preventDefault();
ConfirmationDialog.openNavigateAwayConfirmationModal().then(function () {
firstPass = false;
return $state.go(toState, toParams);
});
firstPass = true;
}
});
#1
11
In general I would say, let's redirect ($state.go()
) only if needed. In other cases, get out from the event listener:
一般来说,我会说,只有在需要时才重定向($ state.go())。在其他情况下,从事件监听器中退出:
if (toState.name === 'login' ){
// doe she/he try to go to login? - let him/her go
return;
}
if(Auth.isLoggedIn()){
// is logged in? - can go anyhwere
return;
}
// else
$state.go('login')
This is simplified logic, but shows, that we should change to execution only if needed. There are some other examles with more detailed implementation and plunkers:
这是简化的逻辑,但表明我们应该只在需要时改为执行。还有一些其他考试有更详细的实施和掠夺者:
- Confusing $locationChangeSuccess and $stateChangeStart
- 困惑$ locationChangeSuccess和$ stateChangeStart
- Angular UI Router: nested states for home to differentiate logged in and logged out
- Angular UI Router:家庭的嵌套状态,用于区分登录和注销
- other example of log in
- 其他登录示例
- angular ui-router login authentication
- angular ui-router登录验证
As provided in the comment, there was plunker, which I changed like this here
正如评论中所提到的,有一个plunker,我在这里改变了
...
// three new lines
if (toState.name === 'specialRoute'){
return;
}
if (fromState.name=='route1'){
event.preventDefault();
$state.go('specialRoute')
}
And this is not looping anymore. Please, check it here
这不再循环了。请在这里查看
#2
5
This answer helped me:
这个答案帮助了我:
$urlRouterProvider.otherwise( function($injector, $location) {
var $state = $injector.get("$state");
$state.go("app.home");
});
Original: Why does AngularJS with ui-router keep firing the $stateChangeStart event?
原文:为什么带有ui-router的AngularJS会继续触发$ stateChangeStart事件?
#3
5
You should use the notify option :
您应该使用notify选项:
$state.go('your.state',{ your params },{notify: false});
This will prevent stateChangeStart to fire again.
这将阻止stateChangeStart再次触发。
#4
0
I simply used $location.path('every/where')
instead of $state.go('every/where')
我只是使用$ location.path('every / where')而不是$ state.go('every / where')
:) .
:)。
#5
0
The infinite loop is partly caused by
无限循环部分是由于
if (toState.name == 'login' ...) { $state.go('login'); ...
..which says if
you're going to the login state, then
go to the login state.
..如果你要进入登录状态,那么就进入登录状态。
...And calling event.preventDefault()
as the first line in the event handler doesn't help. When you use go()
to go to the login screen (or anywhere else), that state change is also prevented by event.preventDefault()
. It should only be used within an if
.
...并且调用event.preventDefault()作为事件处理程序中的第一行没有帮助。当您使用go()转到登录屏幕(或其他任何地方)时,event.preventDefault()也会阻止该状态更改。它应该只在if中使用。
Your entire $stateChangeStart handler should instead be...
你的整个$ stateChangeStart处理程序应该是......
if (!Auth.isLoggedIn() && toState.name != 'login') {
event.preventDefault();
Auth.desiredState = toState.name;
$state.go('login');
}
...which reads naturally. "If
you're not logged in and you're not already going to the login screen, then
stop what you're doing, I'll remember where you wanted to go, and you now go to the login screen."
......自然地读。 “如果你没有登录,而你还没有进入登录界面,那么就停止你正在做的事情,我会记住你想去的地方,现在就进入登录界面。”
Later your Auth
object will issue a $state.go(Auth.desiredState)
when it's satisfied with the user.
稍后,当用户满意时,您的Auth对象将发出$ state.go(Auth.desiredState)。
#6
0
It works for me, Below code helps to get rid of infinite loop
它适用于我,下面的代码有助于摆脱无限循环
let firstPass = true;
$scope.$on('$stateChangeStart', function(event, toState, toParams) {
if ($scope.addForm.$dirty && firstPass) {
event.preventDefault();
ConfirmationDialog.openNavigateAwayConfirmationModal().then(function () {
firstPass = false;
return $state.go(toState, toParams);
});
firstPass = true;
}
});