TLDR;如果您直接在内部导航,OnLoad
您将收到一个 NavigationCancel 事件,其中包含有关 ID 不匹配的消息(我讨厌这个错误!)。你可以像这样避免它:
this.routerEvents.navigationCancel$.pipe(take(1)).subscribe(() =>
{
this.router.navigateByUrl(result);
});
return false;
我不确定大多数人何时使用canLoad
vs.canActivate
但我的具体情况(和解决方案)如下:
AuthGuard
我有一个从我的服务内部显示的登录对话框。显示AuthGuard
对话框,但在用户尝试登录之前不会返回真/假。
- 如果登录失败并且需要将用户重定向到特定页面(例如支持页面),则服务
AuthGuard
返回UrlTree
- 我的“/account”路线是延迟加载的,可能需要几秒钟才能加载
- 我希望在用户单击“帐户”时立即出现登录对话框,因此添加
CanLoad
- 因此,我所做的是将相同的逻辑放入我的
canLoad
处理程序中。这意味着canLoad
如果它首先被击中,它也会显示一个对话框。
- 我让我的
canActivate
警卫运行完全相同的逻辑(别担心 - 你永远不会看到两个对话框)
对于这种情况,我发现最简单的方法是canLoad
:
canLoad(route: Route, segments: UrlSegment[])
{
const currentNavigation = this.router.getCurrentNavigation();
const isInitialNavigation = !currentNavigation.previousNavigation;
if (isInitialNavigation)
{
return true; // always allow load for first navigation (avoids other complications)
}
else {
// returns Observable<boolean | UrlTree>
return showLoginDialog().pipe(map(result => {
if (typeof result === 'boolean') {
return result;
}
else {
// we have a URL tree
// wait for the expected NavigationCancel event and then navigate
this.routerEvents.navigationCancel$.pipe(take(1)).subscribe(() =>
{
this.router.navigateByUrl(result);
});
return false;
}
});;
}
}
我也有一个根提供的RouterEvents
服务,我在其中定义
navigationCancel$ = this.router.events.pipe(filter((e): e is NavigationCancel => e instanceof NavigationCancel));
注意:请注意您是否选择不包括isInitialNavigation
支票。如果您的重定向试图重定向到主页,那么它将不起作用,因为路由器认为您已经在那里。/redirect_home
您可以使用仅重定向到主页的路由来解决此问题- 或更改onSameURLNavigation
设置。