我如何从父路由的后卫重定向到子路由,同时又保护子路由免受直接访问*?
绝对导航问题,当导航到子路径时,将在循环中再次调用父组件上的防护。
相对导航问题是警卫队正在保护父路线,因此尚没有相对于其导航的“已激活路线”。同样,这可能不会保护子路线。也许同一个警卫也可以与子路由或CanActivateChildren一起使用。
Stackblitz示例:https://stackblitz.com/edit/angular-qbe2a7
路线
const appRoutes: Routes = [
{
path: 'foo',
component: FooComponent,
canActivate: [ RedirectionGuard ],
children: [
{
path: 'foo-child',
component: FooChildComponent
}
]
}
];
canActivate()保持警惕
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
console.log('guard: ', route, state, this.route);
// idea: create own ActivatedRoute and give it the values from ActivatedRouteSnapshot which knows about 'foo/'
const foo: ActivatedRoute = new ActivatedRoute();
console.log(foo);
// Error: Cannot match any routes
// I think because there is no route to be relative to when canActivat is called. Router has not yet navigated to '/foo/'
this.router.navigate(['../foo-child'], { relativeTo: this.route
});
// Errors with infinite loop because '/foo/' has this guard which will then be called again
//this.router.navigate(['/foo/foo-child']);
// navigate returns true also. maybe just return that.
return true;
}
*为什么不为您可能要问的所有孩子增加警卫。我需要根据应用程序的状态从父路由重定向到许多不同的子路由。我目前正在使用子路线之一从该组件重定向,但这并不能保护子路线由用户直接导航。
答案 0 :(得分:2)
一种实现此目的的方法可能是使用url参数,在输入父路由时使用canActivateChild和redirectTo子路由。
StackBlitz示例:https://stackblitz.com/edit/angular-redirect-with-params
路由
const appRoutes: Routes = [
{
path: 'foo',
component: FooComponent,
canActivateChild: [ RedirectionGuard ],
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'foo-child-1'
},
{
path: 'foo-child-1',
component: FooChildComponent
},
{
path: 'foo-child-2',
component: FooChildComponent
}
]
},
];
后卫
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
console.log('params:', route.params, route.url);
if (!route.params.skip) {
this.router.navigate(['/foo/foo-child-2', { skip: true }], {
queryParams: { skip: 1 }
});
}
return true;
}
canActivateChild(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) {
return this.canActivate(route, state);
}