角度变化检测错误:ExpressionChangedAfterItHasBeenCheckedError

时间:2018-10-24 10:39:50

标签: angular

当组件内部的输入绑定值从null / undefiend更改为某个值时,出现此错误。下面是示例代码的网址。

https://stackblitz.com/edit/angular-h61csi

为什么会出现此错误?有人请向我解释如何在没有setTimeout的情况下解决此问题。

3 个答案:

答案 0 :(得分:0)

您可以将设置this.selectedItem放在setTimeout中。

setTimeout(() => {
  if(!this.selectedItem) {
    this.selectedItem = this.items[1];
    this.cdr.markForCheck();
  }
});

要了解为什么和何时发生此错误,您可以在此处阅读ExpressionChangedAfterItHasBeenCheckedError-https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

答案 1 :(得分:0)

完全同意@vatz响应,但进行了较小的校正。我们不需要'this.cdr.markForCheck()',仅当我们在组件中使用了onpush更改检测时才需要它。

setTimeout(() => {
  if(!this.selectedItem) {
    this.selectedItem = this.items[1];
  }
});

答案 2 :(得分:0)

我认为解决问题的最佳方法是重新设计组件。您的子组件不应将值传递回父组件,尤其是如果父组件已经知道值是什么,即您的AppComponent确切知道selectedItem和items数组的值是什么,那么您可以将子组件的AfterViewInit挂钩中的逻辑放在父组件中。只需将selectedItem字段更改为:

private _selectedItem: Object;

public get selectedItem() {
    return this._selectedItem ? this._selectedItem : this.items[1];
}

然后从子组件中的AfterViewInit挂钩中删除代码,所有内容都应正常运行而不会出现错误。否则,您将不得不使用setTimeout。