【问题标题】:ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges inangularjsERROR 错误:ViewDestroyedError:尝试使用已破坏的视图:detectChanges inangularjs
【发布时间】:2023-03-14 21:52:01
【问题描述】:

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

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)

【问题讨论】:

  • 你能在这里或闪电战上添加你的代码吗?目前很难理解这个问题

标签: angular ngx-bootstrap angular-changedetection


【解决方案1】:

通常,当您订阅触发更改检测的组件内的外部 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
  }
}

【讨论】:

    【解决方案2】:

    厌倦了所有这些麻烦,当你想更新 UI 时,你可以使用下面的方法。这是变更检测的更好实现,希望在 Angular 文档中提及这一点。

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

    【讨论】:

    • 正是我需要的。谢谢。它可以在没有setTimeout 的情况下工作。
    • 谢谢,Aniket。如果您觉得有帮助,请在此处投票。
    猜你喜欢
    • 2017-10-23
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 2019-10-23
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多