首页 > 解决方案 > ExpressionChangedAfterItHasBeenCheckedError: Expr 在检查后已更改。上一个值:'ngIf: false'。当前值:'ngIf: true'

问题描述

我正在使用 Angular 7 并使用“ng serve”来启动应用程序。我有父子组件,父组件有一个点击按钮,可以翻转一个布尔属性值。如果该布尔属性为真,则显示子组件 (*ngIf)。从子组件中,我发出一个事件,该事件调用父级中的函数,该函数翻转父级中的布尔属性值,导致子组件被删除 (*ngIf)

父组件:

父组件.ts

 capture: boolean = false;
  onCapture () {
    console.log("onCapture called")
    this.capture =  !this.capture;
  }

Parent.component.html

<app-capture *ngIf="capture ==true" (closeCapturePage)="onCapture()"></app-capture>
 <label>
    <img src="/assets/img/camera.svg" alt="" width="32" height="32" title="Open window">
    <input type="button" (click)="onCapture()" id="capture" style="display: none">
  </label>

子组件.ts

@Output() closeCapturePage = new EventEmitter<void>();

closePage() {
      this.closeCapturePage.emit();
}

我可以看到子组件成功发出事件但是遇到错误 ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it is checked。以前的值:'ngIf: false'。当前值:'ngIf: true'

我尝试了类似线程中建议的解决方案,例如在父组件中实现 ngAfterViewChecked 但没有运气。

  show = false;

  ngAfterViewChecked(): void {
  let show = this.capture;
  if (show != this.show) {
    this.show = show;
    this.cdRef.detectChanges();
  }
  }

Stackblitz 示例:https ://stackblitz.com/edit/angular-8efhdm (注意:简单的示例没有复制,所以我添加了启动相机但不记录任何内容的实际代码,没有隐私问题!)

标签: angulartypescriptangular7

解决方案


以防万一有人像我一样寻找答案。我需要的解决方案是了解错误的原因:

https://indepth.dev/posts/1001/everything-you-need-to-know-about-the-expressionchang

当我知道正在发生变化时,将应用这段代码。

由于这个 HTML 代码,我收到了 expressChangedAfterChecked

<relation-mapping *ngIf="loadRelationMappings"
  [mappingPayload]="mappingPayload"
  [mappedRelationIndex]="mappedRelationIndex"
  (mappingPayloadEmitted)="onSentMappingPayload($event)"
  (mappedRelationIndexEmitted)="onSentRelationIndex($event)"
></relation-mapping>

异步调用后的这个变化

this.LS.findAll('MappingPart2', 'master').subscribe( (mappingData: Collection) => {
      console.log('mappingData', mappingData);
      console.log('targetEntity', this.targetEntity);
      // find if class has mappings
      const list = mappingData._items.filter( (lc: Lifecycle) => lc._mapping._clazzReference._name === this.ES.targetNodePath[1].data.name);
      this.mappingPayload = list.length === 1 ? list[0] : null;
      // find if the class has a mapping for the relation the user is on
      if (!!this.mappingPayload) {
        this.loadRelationMappings = true;
        this.mappedRelationIndex = this.mappingPayload._mapping._mappedRelations.findIndex( (relationMapped: RelationMap) => relationMapped._name === this.ES.targetEntity._name);
        this.cd.detectChanges();
        if (this.mappedRelationIndex !== -1 ) {
          this.readRelations = this.mappingPayload._mapping._mappedRelations[this.mappedRelationIndex]._mappedRelationMappings;
        }
      }

      console.log('this.targetMapping', this.mappingPayload);
    });

当我知道变量/值正在更新时添加 this.cd.detectChanges() 为我解决了这个问题。


推荐阅读