Angular 路由器出口外的组件,在路由器通过guard重定向后没有更新其window.location.href?

Angular 路由器出口外的组件,在路由器通过guard重定向后没有更新其window.location.href?,angular,angular-router,angular-changedetection,virtual-dom,Angular,Angular Router,Angular Changedetection,Virtual Dom,我有一个位于路由器外部的导航组件,它利用了一个可重用的图标组件,该组件依赖于绝对url指向SVG图标,该图标通过组件内的getter检索: public get absUrl(): string { return window.location.href.split('#')[0]; } 不幸的是,在重定向时,当从guard触发时,视图没有用新的abs url更新 我已经用setTimeout做了一个变通方法,但是它非常粗糙——它纯粹是为了证明导致问题的链中存在一些延迟,因为最终,

我有一个位于路由器外部的导航组件,它利用了一个可重用的图标组件,该组件依赖于绝对url指向SVG图标,该图标通过组件内的getter检索:

public get absUrl(): string {
    return window.location.href.split('#')[0];
  }
不幸的是,在重定向时,当从guard触发时,视图没有用新的abs url更新

我已经用setTimeout做了一个变通方法,但是它非常粗糙——它纯粹是为了证明导致问题的链中存在一些延迟,因为最终,
window.location.href
的值是正确的

以下是解决方法:

public absUrl = window.location.href.split('#')[0];

  ngAfterViewInit() {
    setTimeout(() => {
      this.absUrl = window.location.href.split('#')[0];
      this.ref.detectChanges();
    }, 200);
  }
  • 只有在以受保护的路由加载整个应用程序时,在加载应用程序后尝试随后访问受保护的路由才能正常工作
  • 当以不存在的路由加载整个应用程序并重定向到/404时会发生这种情况
  • 如果我设置0-100ms超时,它将不会及时更新
  • 通过路由器插座加载的组件工作,图标内的abs url准确更新

有人对如何正确实施这一点有什么想法吗?我的直觉是,如果您试图加载受保护的路由,它与应用程序在第一次加载时的加载方式有关。

我想您可以使用
位置
服务执行类似操作:

public absUrl = window.location.href.split('#')[0];

constructor(location: Location, ref: ChangeDetectorRef) {
  location.onUrlChange((s) => {
    this.absUrl = window.location.href.split('#')[0]);
    ref.detectChanges();
  });
}

为什么不能使用
router.url
属性?@PierreDuc router.url将比仅使用window.location.href更落后,即使在window.location.href工作的情况下,它也不会有更新的值来工作。您的意思是这样的。absUrl=window.location。。。等等这本身不起作用,但如果我在这之后运行一个变更检测周期,它似乎会更稳定地工作。我将在不设置超时的情况下重新测试我的所有用例,以确保这一点适用,并关注变更检测周期。不过,它应该比直截了当的人更有效。谢谢@塞巴斯蒂安,我已经更新了我的答案。我想我有点太仓促了:)无论如何,如果你想阻止使用变更检测器ref,而你只是在模板中使用
absUrl
,你可以考虑使用
可观察的
异步
管道结合使用异步管道仍然会运行变更检测周期,这与调用ref.detectChanges无关,只是更关注性能,在任何情况下,您的解决方案的性能都比使用getter要好得多,getter会在每个变更检测周期与您的位置订阅之间重新计算。它在我所有的用例中都能很好地工作,所有设置超时都被删除了。我现在将此标记为正确的解决方案。你能把这个问题贴到几个月前我问的问题上吗?几乎是同一件事?@SebastianG如果你尝试将所有组件设置为
OnPush
,这将极大地提高性能。是的,我知道
async
确实触发了它自己的更改检测,但它是由angular管理的,因此您不必担心它,也不必让代码变得混乱:)多年来一直在这样做,但谢谢,这是一个很好的建议,顺便说一句,这是我上面提到的另一个线程: