错误错误:ViewDestroyedError:尝试使用被破坏的视图:detectChanges inangularjs

时间:2019-09-09 06:28:08

标签: angular ngx-bootstrap angular-changedetection

我有一个组件客户管理,其中我正在显示客户列表,单击查看按钮,我导航到另一个我在选项卡中显示的组件客户详细信息。客户详细信息组件上显示以下错误

ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges
    at viewDestroyedError (core.js:20452)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:23908)
    at checkAndUpdateView (core.js:23307)
    at callWithDebugContext (core.js:24177)
    at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.js:23879)
    at ViewRef_.push../node_modules/@angular/core/fesm5/core.js.ViewRef_.detectChanges (core.js:21688)
    at ngx-bootstrap-dropdown.js:639
    at HTMLDocument.<anonymous> (platform-browser.js:993)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)

2 个答案:

答案 0 :(得分:1)

在所有这些烦恼中,要更新UI时可以使用以下方法。这是变更检测的更好的实现,希望在Angular文档中有提及。

detectChanges () {
        setTimeout(() => {
            if ( this.cdRef !== null &&
                this.cdRef !== undefined &&
                ! (this.cdRef as ViewRef).destroyed ) {
                    this.cdRef.detectChanges();
            }

        }, 250);
    }

答案 1 :(得分:0)

通常,当您在组件内部订阅触发更改检测的外部Observable时,会发生这种情况。当您不退订销毁组件时,Observable便会触发,并尝试对不再存在的组件进行更改检测。

典型示例:

@Component({...})
class MyComponent {
  Input() myTrigger$: Observable<any>;

  constructor(private cdr: ChangeDetectorRef) {
  }

  ngOnInit() {
    this.myTrigger$.subscribe(() => {
      // do anything useful...
      this.cdr.detectChanges(); // <- This call fails, once the component is destroyed
    });
  }
}

此示例中的解决方案是保留订阅引用,并在销毁时取消订阅。 您不仅应该为变更检测器执行此操作,而且还应该避免一般的严重内存泄漏

@Component({...})
class MyComponent {
  Input() myTrigger$: Observable<any>;
  private sub: Subscription;


  constructor(private cdr: ChangeDetectorRef) {
  }

  ngOnInit() {
    this.sub = this.myTrigger$.subscribe(() => { // <- keep the subscription for later
      ...
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe(); // <- unsubscribe on destroy
  }
}