请向我解释为什么我一直得到这个错误:ExpressionChangedAfterItHasBeenCheckedError:表达式已经改变后,它被检查。

显然,我只有在开发模式下才会遇到这种情况,在我的产品构建中不会出现这种情况,但这非常烦人,而且我根本不明白在我的开发环境中出现错误而不会在prod上显示的好处——可能是因为我缺乏理解。

通常,修复很简单,我只是把导致错误的代码包装在setTimeout中,就像这样:

setTimeout(()=> {
    this.isLoading = true;
}, 0);

或者使用如下构造函数强制检测更改:

this.isLoading = true;
this.cd.detectChanges();

但是为什么我总是遇到这个错误呢?我想要了解它,这样我就可以在将来避免这些俗套的修复。


当前回答

Angular会运行更改检测,当它发现传递给子组件的某些值被更改时,Angular会抛出以下错误:

点击查看更多信息

为了纠正这个问题,我们可以使用AfterContentChecked生命周期钩子和

import { ChangeDetectorRef, AfterContentChecked} from '@angular/core';

  constructor(
  private cdref: ChangeDetectorRef) { }

  ngAfterContentChecked() {

    this.cdref.detectChanges();

  }

其他回答

我希望这能帮助到在座的各位: 我们在ngOnInit中以以下方式调用服务,并使用一个变量displayMain来控制元素到DOM的挂载。

component.ts

  displayMain: boolean;
  ngOnInit() {
    this.displayMain = false;
    // Service Calls go here
    // Service Call 1
    // Service Call 2
    // ...
    this.displayMain = true;
  }

和component.html

<div *ngIf="displayMain"> <!-- This is the Root Element -->
 <!-- All the HTML Goes here -->
</div>

我得到这个错误,因为我在模式中调度redux动作,当时模式还没有打开。我正在调度动作的瞬间模态组件接收输入。所以我把setTimeout放在那里,以确保模式是打开的,然后动作被分派。

我在Ionic3(它使用Angular 4作为其技术堆栈的一部分)中遇到过这种错误。

对我来说,它是这样的:

< ion-icon[名字]= " getFavIconName ()" > < / ion-icon >

所以我试着有条件地改变离子图标的类型,从大头针到删除圈,根据屏幕运行的模式。

我猜我将不得不添加一个*ngIf代替。

请遵循以下步骤:

1. 通过从@angular/core导入'ChangeDetectorRef'来使用它,如下所示:

import{ ChangeDetectorRef } from '@angular/core';

2. 在constructor()中实现,如下所示:

constructor(   private cdRef : ChangeDetectorRef  ) {}

3. 添加下面的方法到你的函数,你正在调用的事件,如点击按钮。它看起来是这样的:

functionName() {   
    yourCode;  
    //add this line to get rid of the error  
    this.cdRef.detectChanges();     
}

我使用的是ng2-carouselamos (Angular 8和Bootstrap 4)

下面这些步骤解决了我的问题:

实现AfterViewChecked 添加构造函数(私有changeDetector: ChangeDetectorRef) {} 然后ngAfterViewChecked(){this.changeDetector.detectChanges();}