【问题标题】:Attempt to use a destroyed view: detectChanges event though the view is detached尝试使用已破坏的视图:detectChanges 事件,尽管视图已分离
【发布时间】:2019-05-09 21:08:10
【问题描述】:

我有一个组件可以进行一些服务调用并获得承诺。承诺解决后,我正在做检测更改。但是有时当组件视图已经被销毁时,承诺会被解决,例如用户关闭的选项卡(我们应用程序的内部选项卡)。在那种情况下,我得到 ViewDestroyedError: Attempt to use a destroyed view: detectChanges。即使我已经分离了我的 tab.component 的销毁阶段的视图。我的问题是我在这里做错了什么?

我试图将视图从销毁阶段的更改检测中分离出来,但没有运气,在销毁阶段后承诺正在解决,并且仍然调用 detectChanges。我确实理解 ngOnDestroy 实际上并没有销毁该类,并且其中的代码将在垃圾收集阶段被销毁。

这是我的 tab.component 中导致问题的示例代码

const promises:Promise<any>[] = [];
_.each(types, (type:string) => {
  promises.push(this.service.getResultsBy(type))
})
Promise.all(promises)
.then((data) => {
  //some code here
  this.cd.detectChanges();
})

ngOnDestroy 中,我将视图与 CD 分离

ngOnDestroy() {
    this.cd.detach();
  }

在这种情况下,承诺对我来说很重要,因为即使组件被销毁,我也确实需要进行一些计算/状态保存。我只是想了解如何将视图分离得足够好,以使我在 promise 中的代码不会导致更改检测尝试。

【问题讨论】:

    标签: angular promise angular2-changedetection


    【解决方案1】:

    不需要从ngOnDestroy 上的更改检测中分离,也不会帮助解决此错误。但是,在调用 ngOnDestroy 之后,您不能再调用 detectChanges。使用 observable,您可以取消订阅 ngOnDestroy 中的 observable。无法取消订阅 Promise,因此您需要在组件中保留一个标志。

    export class MyComponent {
    
      private destroyed = false;
    
      ngOnDestroy() {
        this.destroyed = true;
      }
    
      triggerChangeDetection() {
        if (!this.destroyed) {
          this.cd.detectChanges();
        }
      }
    
    }
    

    【讨论】:

    • 我想如果我从变更检测中分离,Angular 会理解视图已经分离并且不会尝试更新它,但我同意它没有帮助。我最终检查了视图是否在我的承诺中被破坏,就像这样'if (this.cdRef["destroyed"]) { // my code here}。几乎和你说的一样,只是没有保留旗帜。非常感谢您的回答,如果有人会提供更好的解决方案,我会一直保留这个问题。
    • 明白。与变更检测分离将阻止 Angular 调用 detectChanges,但它不会阻止您或支持您自己手动调用 detectChanges。否则它不会有用。它适用于应用程序开发人员知道如何更有效地触发更改检测以便开发人员可以分离然后自行调用detectChanges 的用例。
    猜你喜欢
    • 2017-10-23
    • 1970-01-01
    • 2017-12-13
    • 2023-03-14
    • 2016-10-17
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多