我的路线设置如下:
export const APP_ROUTES: Routes = [
{
path: '',
resolve: {
user: CurrentUserResolver
},
children: [
{
path: ':sectionKey',
canActivate: [SectionAccessGuard],
children: [
{
path: 'dashboard',
component: DashboardComponent
}
]
}
]
}
]
父路由将通过HTTP调用检索用户,并且我希望仅当前用户有权访问我的子路由:sectionKey
。问题是,看起来我的canActivate SectionAccessGuard
在快照完全填充之前被调用:
@Injectable()
export default class SectionAccessGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
console.log(route.data);
console.log(route);
return true;
}
}
在控制台中,第一个条目没有任何内容;但是,第二个条目最终将填充user
字段。
我知道canActivate
方法也可以返回Observable<boolean>
,但是我没有看到任何关于如何等待解析完成的挂钩。
我在这里缺少什么?我觉得这应该是非常直接的。我目前正在使用angular v4.0.0-rc.2
答案 0 :(得分:1)
我发布此消息已经过去了大约8个月,所以我会更新我们最终的结果:
根据组件的位置(this.route.parent.parent.parent.data.user
),通过结算将数据存储在路由器中变得非常尴尬,因此我们不再使用结算,而是使用NgRx来存储这类信息
然后我们的警卫负责触发数据的获取,并等待它完成。像这样:
@Injectable()
export class AuthenticationGuard implements CanActivate {
constructor(private router: Router, private store: Store<ApplicationState>) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
this.store.dispatch(new AuthenticateAction());
return this.store
.select('auth')
.filter((s) => !!s && !s.authenticating)
.map((s) => s.authenticated)
.take(1);
}
}
如果状态中有几个标志(经过身份验证和身份验证),则告诉警卫我们在此过程中的位置。
答案 1 :(得分:0)
我不确定在解析器完成后是否可以强制执行防护工作,但我尝试将代码从解析程序移动到canActivate()。
当获取当前用户信息的observable返回数据时,应用您的逻辑来检查是否允许用户导航到该路径。
答案 2 :(得分:0)
我也在努力解决这个问题,我希望看到更多来自Angular团队的文档。似乎canActivate不会等到父母完成之后才开始运行,但是解决方案确实如此。
您可以将激活的代码更改为另一个解决方案,因为子解析会等待父解析。如果更改为已解决,您将通过route.parent.data.user访问该用户,然后您可以调用router.navigate,如果用户未经授权,则离开该部分。
另一种方法是设置一个可以注入解决防护和canActivate防护的服务。你必须从决心后卫中设置一个观察者并在canActivate后卫中订阅它。