Angular7:如何检测NavigationCancel的原因

Angular 7: How to detect the reason of NavigationCancel

类似的事情告诉我事件 NavigationCancel 发生了,但我想知道是什么触发了那个事件:

例如AppComponent(摘录):

constructor (
  ....
  private router: Router
)  {
     router.events.subscribe(e => {
       if (e instanceof NavigationCancel) {
         // PLEASE TELL ME, WHO DID CALL ME ? <---
       }
     });
   }

每次我刷新浏览器时,某些东西(守卫、msal 等)都会删除路由,最后访问的 route 消失了。目前无法进行深层链接。

解决方法是:我必须将最后一条路线保存在 LocalStorage 中并强制应用程序切换到该路线。也许如果我能找到触发因素,也许我会找到另一个解决方案。

NavigationCancelCanLoadCanActivate 守卫阻止子路由加载时发生。如果您想调试您的路由器事件,请将 enableTracing: true 添加到您的 RouterModule configuration. Also, NavigationCancel has a reason property 中,这可能会有有用的信息。

创建一个在守卫失败时收到通知的服务可能适合您。

如您所见here您无法挂钩路由器服务,因此守卫需要一些样板代码。如果它 returns false 调用你的服务,那会存储警卫错误。

不要忘记删除导航开始事件中的错误。

您可以向 Angular 团队发出功能请求以创建这样的挂钩,以便能够发现守卫错误。

除了 boolean,您还可以 return 来自带有额外参数的守卫 UrlTree。因此,如果您要重定向到 /home,您会这样做:

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (!this.authService.isLoggedIn) {
      return this.router.createUrlTree(['/home', { message: 'You shall not pass' }]);
    } else {
      return true;
    }
  }

然后你可以在目标位置用ActivatedRoute#params阅读这个message

示例取自 here

刚遇到同样的问题,找到了调试方法。将 Router 注入您的页面组件并订阅其事件,如下所示:

this.router.events.subscribe(e => {
  // using `instanceof` you can filter the events of interest
  if (e instanceof NavigationCancel) debugger;
})

在浏览器中打开 DevTools,并尝试重现该问题。当调试器被激活时,仍然很难找到根本原因。我不得不向下滚动 Stack Trace 并查看一些内部 Angular/RxJS 代码,以便找到具有不同 id 的新 导航事件何时被触发。

在我的例子中,结果是我在之前的导航解决之前过早地间接调用了 router.navigate。这就是看到该错误的原因:“导航 ID 2 不等于当前导航 ID 3”- Angular 路由器检测到已触发新导航(id=3),因此取消了之前的导航( id=2),这几乎完成了。结果,我遇到了过时的查询参数的问题。

在第二次导航解决问题之前引入人为延迟。