即使使用异步EventEmitter,也要获取ExpressionChangedAfterItHasBeenCheckedError

时间:2018-11-01 10:23:19

标签: angular typescript

这个异常困扰着我,但我不明白这里的问题是什么。我有一个FormArray,可将新项目推送到其控件中。这些控件向下传递到其他子组件:

<mat-card *ngFor="let itemFormGroup of formArray.controls">
  <app-item [formGroup]="itemFormGroup">
  </app-item>
</mat-card>

但是,我已经尝试了几种方法,但是它没有用。我现在已经尝试使用EventEmitter<any>(true)setTimeout()等,但是我并没有摆脱这种例外情况

@Output()
addItem = new EventEmitter<any>(true);

onMenuSelected(item) {
  this.addItem.emit({date: this.date, item: item});
}

父母:

onAddItem(event) {
  const formArray = <FormArray> this.form.get(event.date);
  formArray.push(this._formBuilder.group(event.item));
}

错误:

  

ExpressionChangedAfterItHaHasBeenCheckedError:检查表达式后,表达式已更改。先前的值:“ ng-valid:true”。当前值:“ ng-valid:false”。

由于我没有设置任何名为valid的属性,因此我假设是表单本身在周期中更改该属性并破坏了内容。

如何避免这种情况?


这是父级构造FormArray的方式。整个过程都是一个日历,基本上是一个巨大的FormGroup,格式为

// pseudo code

form: FormGroup {     // Form of the entire calendar
  date1: FormArray [  // First day in the calendar with a list of items
    item1: FormGroup, // An item in the calendar
    item2: FormGroup
  ],
  date2: FormArray [
  ]
}

以下是构建它的逻辑:

refreshCalendar() {
  const groups = {};

  this.dates.forEach(d => {
    groups[d] = this._formBuilder.array([]);
  });

  if (Object.keys(groups).length > 0) {
    this.form = this._formBuilder.group(groups);
  }

  this.formValueChange$ = this.form.valueChanges.subscribe(() => {
    setTimeout(() => {this._calendarComponentService.setDirty(this.form.dirty);}, 0);
  });

  // This call is important after resetting in order to propagate the 'dirty' state
  this.form.updateValueAndValidity();

  this.updateItems();
}

updateItems() {
  if (Object.keys(this.items).length > 0) {
    for (const k of Object.keys(this.items)) {
      const formArray = <FormArray> this.form.get(k);
      if (formArray == null) {
        continue;
      }
      for (const item of this.items[k]) {
        formArray.push(this._formBuilder.group(item));
      }
    }
  }
}

1 个答案:

答案 0 :(得分:1)

在插入新项目后尝试注入ChangeDetectionRef并调用detectChanges()。