首页 > 解决方案 > Angular 6:根据 URL 参数更改组件的内容,内容更改滞后

问题描述

在我的 ngOnInit 中,我订阅了一项服务,映射出一个对象并在我的模板中呈现所述对象。

  ngOnInit() {
    this.id = +this.route.snapshot.paramMap.get('id');
    this.privateService.someService(this.id)
      .pipe(
        take(1)
      )
      .subscribe(
      (response) => {
        this.mapRes = response;
        }
      )
  }

当 url 参数中的 id 发生变化时,我将根据新的 Id 更改模板中的数据。我还使用 rxjs take() 运算符来使异步操作更容易且更少滞后。但是,滞后仍在继续。从我将 url 参数更改为使用新数据重新渲染的模板几乎需要一秒钟。

ngDoCheck() {
   let tempId = +this.route.snapshot.paramMap.get('id');
    if(this.id === tempId) {
      return;
    }
    else {
      this.privateService.someService(this.id)
      .pipe(
        take(1)
      )
      .subscribe(
      (response) => {
        this.mapRes = response;
        }
      )
      this.id = tempId;
    }
  } 

我认为这种滞后正在发生,因为我仍然在我的 ngOnIt 中订阅了 someService,然后我在 ngDoCheck() 挂钩中重新订阅了该服务。

如何在不使用被销毁的组件的情况下取消订阅服务(这里就是这种情况),以便我可以重新渲染相同的组件但使用不同的数据?

编辑:我想知道我的问题是否是模板更改改变了实际的 dom,这是滞后而不是流的来源?因为在 ngDoCheck 被触发后,我使用 take() 操作符只得到了 1 个对象,所以理论上流会停止

标签: angularrxjsobservable

解决方案


是的,在 ngDoCheck 中重新订阅可能会创建许多订阅,并且取决于一次屏幕上有多少组件实例,这个问题会成倍增加。但真正的问题是每次 ngDoCheck 触发时您都试图处理服务调用。如果您在该回调中放置一个 console.count,我敢打赌您会看到该服务调用启动了许多请求。相反,在初始化时,您将希望通过订阅 route.params 或 route.paramsMap 或 router.events 来订阅路由的更改。由于 paramsMap 是一个异步 Observable,它可能会立即移动到您的else块并在每个 doCheck 上触发请求。


推荐阅读