在我的表格组件中检查了表达式后,表达式已更改

时间:2019-11-25 04:29:24

标签: angular angular-forms

我建立了一个表格组件ez-table,它允许您将模板传递到该列以呈现当前项目。这一切都很好,但是由于某种原因,当我有一个表单字段的验证属性依赖于另一个表单字段中的数据时,出现错误

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
Previous value: 'ng-valid: true'. Current value: 'ng-valid: false'.

如果更改一个字段的值会使另一个字段无效。

在下面的示例中,如果行中的一个字段具有值,则另一个字段必填。

<form #form="ngForm">
  <ez-table [data]="rows">
    <ez-column heading="Val 1" property="val1">
      <ng-template let-row let-i="index">
        <input [name]="'val1_' + i" [(ngModel)]="row.val1" [required]="!!row.val2">
      </ng-template>
    </ez-column>
    <ez-column heading="Val 2" property="val2">
      <ng-template let-row let-i="index">
        <input [name]="'val2_' + i" [(ngModel)]="row.val2" [required]="!!row.val1">
      </ng-template>
    </ez-column>
  </ez-table>
  Valid: {{ form.valid | json }}
</form>

我无法理解为什么在没有组件的情况下可以做完全相同的事情并且没有收到错误时在表组件中发生这种情况。

此表的作用完全相同,但是将数据输入一个字段不会触发错误,但是会更新表单的有效性。

<form #form2="ngForm">
  <table>
    <thead>
      <tr><th>Val 1</th><th>Val 2</th></tr>
    </thead>
    <tbody>
      <tr *ngFor="let row of rows2;index as i">
        <td>
          <ng-container *ngTemplateOutlet="editTemplate1;context:{ $implicit: row, index: i }">
          </ng-container>
        </td>
        <td>
          <ng-container *ngTemplateOutlet="editTemplate2;context:{ $implicit: row, index: i }">
          </ng-container>
        </td>
      </tr>
    </tbody>
  </table>

  Valid: {{ form2.valid | json }}

  <ng-template #editTemplate1 let-row let-i="index">
    <input [name]="'val1_' + i" [(ngModel)]="row.val1" [required]="!!row.val2">
  </ng-template>

  <ng-template #editTemplate2 let-row let-i="index">
    <input [name]="'val2_' + i" [(ngModel)]="row.val2" [required]="!!row.val1">
  </ng-template>
</form>

这是一个StackBlitz

https://stackblitz.com/edit/angular-k58bmn?file=src/app/app.component.html

,表组件的源代码位于

https://github.com/adriandavidbrand/ngx-ez/blob/master/projects/ngx-ez/src/lib/ez-table/components/ez-table/ez-table.component.html

1 个答案:

答案 0 :(得分:2)

在组件中添加detectChanges。

修正:https://stackblitz.com/edit/angular-xsgyqj

import { Component, ChangeDetectorRef } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  rows = Array.from({ length: 5 }, () => ({}));
  rows2 = Array.from({ length: 5 }, () => ({}));

  constructor(private changeDetection: ChangeDetectorRef) {}

  ngAfterContentChecked() {
    this.changeDetection.detectChanges();
  }
}