33

我在我的 Angularv5 应用程序中使用@ngrx/router-store并且我最近开始遇到一个错误:(Navigation ID X is not equal to the current navigation id Y其中 X 和 Y 是整数)。

当我从特定路线 B ​​导航到路线 A 时,这个问题一直发生。从任何其他路线导航到路线 A 似乎工作正常。

我发现的与此相关的唯一其他SO 问题提供了该问题可能是由多次快速更新导航引起的。为了测试这是否发生(不应该发生),我在根组件中订阅了路由器导航事件,在订阅中设置了一个断点,并打开了一个调试会话来逐步解决问题。这样做,我可以看到

  1. 假设当前导航 ID 是 11。当我导航到问题路线时,路由器开始导航,成功执行每个导航事件,包括NavigationEnd然后立即 @ngrx/router-store 抛出一个'ROUTER_CANCEL'动作,说明:Navigation ID 12 is not equal to the current navigation id 13。据我所知,12 是正确的导航 ID(同样,导航 ID 11 完成并立即'ROUTER_CANCEL'被抛出,而路由器不会发出任何进一步的导航事件)。此外,'ROUTER_CANCEL'操作负载包含导致问题的路由器导航事件以及导致问题时商店的状态。导致问题的事件的 ID 为 12,当时商店中的路由器状态的 ID 为 11。因此,12 似乎是正确的导航 ID,不应该引发错误。

  2. 在从问题路由导航到用户配置文件路由时,在 @ngrx/router-store 取消导航之前不会发生其他导航。(即我没有快速更新导航路线)

  3. 除了 ngrx 调度'ROUTER_CANCEL'操作之外,不会报告任何错误(也不会引发错误)。

同样,除非导航从特定路线 B ​​开始,否则遇到问题的路线工作正常。据我所知,这条特定路线 B ​​没有什么不同或不寻常的(问题路线 A 也不关心人们来自哪里——这两条路线彼此没有关联)。

最后一件事:在调试会话之外触发错误似乎总是会导致表单Navigation ID X is not equal to the current navigation id X+1中的错误,但是在调试会话中触发错误可能会导致Navigation ID 11 is not equal to the current navigation id 15orNavigation ID 13 is not equal to the current navigation id 20等​​。

有谁知道发生了什么?我对@ngrx/router-store 不够熟悉,无法真正猜测这可能是如何发生的。我的假设是,当@ngrx/router-store 接收到事件时,商店中的导航 ID 值会同步增加NavigationEnd所以我什至不确定这些 id 是如何出现乱序的——更不用说在这种情况下id 似乎是正确的。

任何想法都非常感谢!

PS:我很高兴发布代码,但我的应用程序很大,我不知道这个错误是从哪里触发的。

4

5 回答 5

42

我想到了!调用事件的组件有代码。所以答案类似于这个 SO 问题中的答案(迅速改变路线)。router.navigate()NavigationEnd

我收到此错误是因为我连续两次调用 router.navigate (1 次追加 queryParams,1 次追加片段)所以不得不重构我的代码只调用一次导航。

于 2018-05-13T14:47:47.870 回答
4

将发布答案,因为我遇到了类似的问题,但很难找到它发生的原因。希望它会帮助其他人在这里结束......

遇到此问题时,它也可能是由调用重置查询参数引起的。例如在ngOnDestroy方法调用中:

public ngOnDestroy(): void {
  // Removing query params on destroy:
  this.router.navigate([], {
    relativeTo: this.route,
    queryParams: {},
    queryParamsHandling: 'merge',
    replaceUrl: true,
  });
}

在该方法中,路由中存在的任何查询参数都将在ngOnDestroy组件的方法中删除。由于这种方法,路线变化迅速,与@John 在他的回答中提到的相似。它导致了同样的问题:NavigationCancel事件被触发并带有以下消息:

NavigationCancel {id: x, url: "/parent/child", reason: "Navigation ID x is not equal to the current navigation id x+1"}
  id: x
  url: "/parent/child"
  reason: "Navigation ID x is not equal to the current navigation id x+1"

因此NavigationEnd,永远不会开火。


注意:您可以在路由器配置中启用跟踪,ExtraOptions并将参数enableTracing设置为true,以便更轻松地调试此问题。

于 2020-03-19T07:45:43.183 回答
3

就我而言,我只是在组件的constructor. 不要那样做。它取消当前导航,因为它还没有完成。导航到里面ngOnInit,因为导航已经完成,你可以自由地导航到其他地方。

于 2020-11-05T03:24:13.343 回答
2

我遇到了完全相同的问题,但找到了另一个原因来解释它。


TL;博士

所以这不起作用:

<a (click)="navigateTest()" href="#">click me</a>

而这有效!

<a (click)="navigateTest()">click me</a>

详细解答

在我的模板中

<a (click)="navigateTest()" href="#">click me</a>

在我的组件中

public navigateTest(): void {
    this.router.navigate(['/my-destination']);
}

首先我激活了路由器调试跟踪(enableTracing: true在路由器forRoot定义中)

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {useHash: true, enableTracing: true})
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

我看到我有一个NavigationStart事件id: 2, url: '/my-destination' navigationTrigger: 'imperative'

然后我有另一个NavigationStart活动id: 3, url: '/' navigationTrigger: 'popstate'

没想到这个!

有时(并非总是),我也有他们之间的NavigationCancelled事件id:2,有原因Navigation ID 2 is not equal to the current navigation id 3

经过数小时的调试,我发现这是因为href="#"我的模板上的 HTML 元素...

于 2020-05-04T15:00:16.800 回答
-3

我遇到了同样的问题,我被困了一个星期,直到我清理了我的浏览数据,一切正常。

于 2020-04-01T21:09:26.620 回答