angular 禁用路由器位置订阅

jhkqcmku  于 4个月前  发布在  Angular
关注(0)|答案(7)|浏览(44)

🚀功能请求

相关包

@angular/router

描述

我们正在使用createCustomElement()将支持路由的Angular组件 Package 为Web组件。目前这运行得很好,但当组件卸载时,路由器仍然监听位置变化并执行路由。我希望找到一种方法来关闭它,但没有找到。
我尝试过dispose()方法,但由于路由器示例似乎被保持活跃,所以当我第二次加载Web组件时,它将停止处理路由。
我想要做的是在我的应用中销毁Web组件时停止locationSubscription,或者让initialNavigation()处理第二次调用,重置路由器。有没有办法实现这个功能?

dauxcl2d

dauxcl2d1#

你正在运行哪个版本?听起来像是在11.2.0版本中,#40638 实现了你需要的功能。

snz8szmq

snz8szmq2#

@crisbeto 版本11.2.0是我使用的,但我不确定这是否能解决我的问题,因为我认为在这种情况下不应该重用路由器。
当我将组件注册为自定义元素时,我需要将其传递给注入器。当组件被定义时,没有办法再次这样做。因此,从我的理解来看,当我的组件第二次被使用时,会使用相同的注入器,从而给我相同的路由器示例。从渲染的Angular 来看,当我的组件第二次渲染时,它应该是一个全新的组件,意味着一个全新的路由器示例。但我不知道如何实现这一点。
如果我在ReportTestComponent中调用router.dispose(),当我第二次使用自定义元素时,路由器就死了,它包含了之前渲染元素中使用的路由的所有“历史记录”。
这是用于自定义元素注册的代码:

export class AppModule {
  constructor(
    private injector: Injector
  ) {}

  ngDoBootstrap(appRef: ApplicationRef): void {
      if (!customElements.get("report-test")) {
        const reportTestComponent = createCustomElement(ReportTestComponent, {
          injector: this.injector
        });

        customElements.define("report-test", reportTestComponent);
      } else {
        console.debug("custom element report-test is already registered");
      }
  }
}
r8uurelv

r8uurelv3#

路由器位于“根”级别,因此只有一个示例。这就是为什么调用 dispose 会影响到所有组件的原因。
你可以尝试使用 resetConfig 代替。
然而,仍然存在一些问题。例如,如果同时有两个组件的示例怎么办?但那是另一个故事了 🤷🏽‍♂️
祝好运!
闪亮的 Flash ⚡

lstz6jyr

lstz6jyr4#

@flash-me resetConfig 的值不够,因为它并没有真正地“重启”路由器内部之前导航和转换的值。
这里的“根”级别是什么?窗口?
虽然我理解了在同一个页面上使用内部路由的两个不同组件可能会导致问题,但我们可以处理这种情况。现在的问题是,当我第二次加载我的组件时,路由器被重复使用了,而我原本希望这种情况是我能够更好地控制的。

yyhrrdl8

yyhrrdl85#

这个问题有任何更新吗?

mf98qq94

mf98qq946#

我们也面临着在Angular更新9到16版本之后相同的问题。

2fjabf4q

2fjabf4q7#

在Angular 16项目中解决类似问题的要点如下:

  • 不要销毁路由器

为了进行导航,请保持路由器示例的活跃状态。一旦你销毁了它,你就无法重新初始化。所以从你的代码中删除router.dispose()

  • 避免在加载时进行相同的URL导航

不要在生命周期事件上导航到相同的URL。如果仍然需要这样做,那么请检查查询参数是否发生了变化,只有在此情况下才触发导航。

const queryParams =  this.activatedRoute.snapshot.queryParams;
if (!isEqual(queryParams, this.queryParams) {
    this.queryParams = queryParams;
    this.router.navigate([], params);
 }
  • 路由器守卫

如果上述两点不起作用,那么可以使用路由器守卫来根据你的应用程序流程限制导航。

相关问题