以可变状态加载角度为ui-router的路由器
问题描述:
根据用户的权限,我有两种默认状态之一(我们称之为foo
和bar
)在登录后显示。我有一个在$stateChangeStart
上运行的函数,它使用用户的权限将它们重定向到正确的屏幕。以可变状态加载角度为ui-router的路由器
foo
权限 - >mybrokenapp.com/foo/dashboard
bar
权限 - >mybrokenapp.com/bar/dashboard
这工作完全在用户通过登录页面进入。但是,如果用户登录(设置了cookie)并仅访问根URL(mybrokenapp.com
),则重定向不再起作用。
我已调试到99%确定该错误是由于运行$stateChangeStart
时未设置currentRole
造成的。
路由代码:
$stateProvider
.state('app', {
templateUrl: '/path/app.html',
url : '',
resolve: {
authenticated: ['authService', function(authService){
return authService.authenticationStatus(true);
}]
}
})
.state('app.foo', {
abstract: true,
template: '<ui-view/>',
url: "/foo"
})
.state('app.foo.dashboard', {
templateUrl: '/path/dashboard.foo.html',
url: "/dashboard",
controller: 'DashFoo',
controllerAs: 'dashFoo'
})
.state('app.bar', {
abstract: true,
template: '<ui-view/>',
url: "/bar"
})
.state('app.bar.dashboard', {
templateUrl: '/path/dashboard.bar.html',
url: "/dashboard",
controller: 'DashBar',
controllerAs: 'dashBar'
})
.state('login', {
templateUrl: '/path/login.html',
url: "/login",
controller: 'LoginCtrl'
})
一个重定向到基于权限正确的URL的功能:
.run(function($rootScope, $state, authService, userService){
authService.initialize('/api', true);
$rootScope.$on('$stateChangeStart', function (event, toState) {
if (toState.name === 'app') {
if (userService.getUserRoles().currentRole == 'foo') {
event.preventDefault();
$state.go('app.foo.dashboard');
}
if (userService.getUserRoles().currentRole == 'bar') {
event.preventDefault();
$state.go('app.bar.dashboard');
}
}
});
});
就如何解决这个问题,或者替代路线的设计,还是任何想法提供相同的功能,将不胜感激。
答
我自己设法解决了这个问题。在ui-router github pages中发现了这个有趣的讨论。
添加做出决议初始化状态的定义与决心:
问题要解决{}可以访问由UI路由器内部使用的实际解决的对象,并允许$ stateChangeStart内
的代码:
.run(function($rootScope, $state, authService, userService, $timeout){
authService.initialize('/api', true);
$rootScope.$on('$stateChangeStart', function (event, toState) {
if (toState.name === 'app') {
toState.resolve.x = function() {
$timeout(function(){ userService.setUserRoles(authService.user); }, 30).then(function(){
if (userService.getUserRoles().currentRole == 'foo') {
event.preventDefault();
$state.go('app.foo.dashboard');
}
if (userService.getUserRoles().currentRole == 'bar') {
event.preventDefault();
$state.go('app.bar.dashboard');
}
});
};
}
});
});
30 milisecond超时需要,得到authService
时间来加载。虽然这并不理想,但它的工作原理。
对上述代码的任何改进都值得欢迎。
答
请检查我在这个问题中给出的答案。它提供了替代和可以更好的设计 Angular Authentication and Access control
在答案u可以根据您的需要轻松扩展boolean authenticate
参数。并且仅在$ stateChange事件中调用认证服务。