导航ID不等于当前路由器导航ID错误

时间:2018-05-13 13:46:29

标签: angular ngrx angular-router ngrx-router-store

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

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

我发现的唯一其他S.O. issue related to this提供了多次快速更新导航可能导致问题的可能性。为了测试这是否发生(它不应该),我订阅了我的根组件内的路由器导航事件,在订阅中设置了一个断点,并打开了一个调试会话来逐步解决问题。这样做,我可以看到

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

  2. 在从问题路线导航到用户个人资料路线时,在@ ngrx / router-store取消导航之前不会进行其他导航。 (即我没有快速更新导航路线)

  3. 除了ngrx调度'ROUTER_CANCEL'操作外,不会报告任何错误(并且不会抛出任何错误)。

  4. 再次,遇到问题的路线工作正常,除非导航从特定路线B开始。据我所知,这条特定路线B没有什么不同或不同寻常的问题路线A也不关心人们来这里from - 两条路线彼此没有关联。)

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

    有没有人有任何想法发生了什么?我对@ ngrx / router-store不太熟悉,不能真正猜出这可能会发生什么。我的假设是,当@ ngrx / router-store收到Navigation ID 13 is not equal to the current navigation id 20事件时,商店中的导航ID值会同步增加,因此我甚至不确定ID是如何所有出现故障---更不用说这种情况下ids似乎是正确的。

    非常感谢任何想法!

    PS:我很乐意发布代码,但我的应用程序很大,而且我没有任何关于触发此错误的线索。

5 个答案:

答案 0 :(得分:15)

我明白了!在router.navigate()事件中调用NavigationEnd的组件中有代码。所以答案类似于this S.O. issue中的答案(快速改变路线)。

答案 1 :(得分:3)

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

遇到此问题时,也可能由调用重置查询参数引起。例如,在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将永远不会触发。


注意:您可以SO: How to specialize std::hash::operator() for user-defined type in unordered containers?将参数enableTracing设置为true,以便更轻松地调试此问题。

答案 2 :(得分:1)

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


TL; DR

所以这没有用:

<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的{​​{1}}事件

然后我还有另一个id: 2, url: '/my-destination' navigationTrigger: 'imperative'的{​​{1}}事件

这不是预期的!

有时候(并非总是如此),我之间也有NavigationStart的{​​{1}}事件,原因为id: 3, url: '/' navigationTrigger: 'popstate'

经过数小时的调试,我发现这是由于HTML上的NavigationCancelled是模板上的一个元素...

答案 3 :(得分:0)

就我而言,我只是在组件的constructor内部导航。不要那样做因为当前导航尚未完成,所以它取消了。在ngOnInit内导航,因为导航已完成,您可以随意导航到其他地方。

答案 4 :(得分:-2)

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