在我的表格组件中检查后,表达式发生了变化

Posted

技术标签:

【中文标题】在我的表格组件中检查后,表达式发生了变化【英文标题】:Expression has changed after it was checked in my table component 【发布时间】:2020-03-20 08:33:39 【问题描述】:

我已经构建了一个表格组件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

【问题讨论】:

或者,您可以尝试在 .ts 文件的 @component 指令中使用 changeDetection: ChangeDetectionStrategy.OnPush 已经试过了 【参考方案1】:

在您的组件中添加 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();
  

【讨论】:

以上是关于在我的表格组件中检查后,表达式发生了变化的主要内容,如果未能解决你的问题,请参考以下文章

表达式___在检查后发生了变化

检查后表达式发生了变化 - 角度

例外:在检查离子输入后,表达式发生了变化

Angular 2 / PrimeNG - 表达式在检查后发生了变化。在最后一个无效的表单控件上绑定 NgModel

使用反应式表单在 Angular 中检查后,表达式发生了变化

当组件属性取决于当前日期时间时,如何管理Angular2“检查后表达式已更改”异常