我使用常规拦截器方法来限制对某个状态的访问,并且只允许经过身份验证的用户。未经过身份验证时,用户将重定向到登录页面。这很好。
我还会收听状态更改事件以显示加载微调器。哪个也好。但是,通过重定向,$stateChangeStart
会被触发两次,但$stateChangeSuccess
,$stateChangeError
甚至$viewContentLoaded
只会触发一次。
当登录页面当前加载时尝试访问安全状态时出现问题。 $stateChangeStart
事件已触发,但$stateChangeSuccess
,$stateChangeError
或$viewContentLoaded
事件并非如此,这使得我的微调器会永久加载。请参阅下面的示例。
// module.config()
$stateProvider.state({
name: 'home',
url: '/home',
controller: function() {},
templateUrl: 'home.html'
});
$stateProvider.state({
name: 'login',
url: '/login',
controller: function() {},
templateUrl: 'login.html'
});
$stateProvider.state({
name: 'secure',
url: '/secure',
controller: function() {},
templateUrl: 'secure.html'
});
// module.run()
$rootScope.$on('$stateChangeStart', function() {
console.log('$stateChangeStart: starting loading spinner');
});
$rootScope.$on('$stateChangeSuccess', function() {
console.log('$stateChangeSuccess: stopping loading spinner');
});
$rootScope.$on('$stateChangeError', function() {
console.log('$stateChangeError stopping loading spinner');
});
$rootScope.$on('$viewContentLoaded', function() {
console.log('$viewContentLoaded stopping loading spinner');
});
$rootScope.$on('$stateChangeStart', function(event, toState) {
if (toState.name == 'secure') {
$state.go('login');
event.preventDefault();
}
});
我可以通过在重定向期间手动触发事件来停止我的微调器,但我希望在调用{{1}时自动触发其他事件之一}在重定向状态中明确强制执行通知{{1也不起作用。拦截状态更改时,事件与重定向不同步。因此,当启动事件被触发两次时,我的第二次观察,但其他只是一次。
答案 0 :(得分:1)
怎么样:
$rootScope.$on('$stateChangeStart', function(event, toState) {
event.preventDefault();
if (toState.name == 'secure') {
$state.go('login');
} else {
//go to toState
}
});
这种方法将首先停止转换,然后开始一个新的转换,这反过来应该激活将停止你的微调器的监听器。
答案 1 :(得分:0)
解决方案是在拦截器中强制执行状态重新加载,如下所示:
preventDefault()
但是,这仍然可能会造成问题,因为$state.go('login', {}, {notify: true});
执行了两次。此外,因为重新加载可能会触发状态$rootScope.$on('$stateChangeStart', function(event, toState) {
if (toState.name == 'secure') {
$state.go('login', {}, { reload: true });
event.preventDefault();
}
});
这可能是angular-ui-router中的错误或遗漏功能吗?