一起使用 disabled、ngModel 和 ngModelChanged 绑定会抛出 ExpressionChangedAfterItHasBeenCheckedError

Using disabled, ngModel and ngModelChanged bindings together throws an ExpressionChangedAfterItHasBeenCheckedError

请看示例:https://stackblitz.com/edit/angular-bvcrcz

我的模板中有 <mat-checkbox [ngModel]="row.IsVerified" [disabled]="row.IsVerified" (ngModelChange)="setTrue()"></mat-checkbox>

setTrue 方法如下所示: setTrue = () => { ObservableOf(67).subscribe(_ => { this.row.IsVerified = true; // This throws a ExpressionChangedAfterItHasBeenCheckedError!!! }); }

我想要实现的是:单击复选框不应立即更改 ngModel 值,而是应该触发对服务器的调用(以更新值在服务器上),并在成功响应代码后,将 ngModel 设置为 true

设置 ngModel 应该反过来禁用复选框以禁止用户再次单击它。

但是,我收到一条错误消息(在控制台中):ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ng-untouched: true'. Current value: 'ng-untouched: false'.

我应该怎么做才能消除错误?

您应该删除 HTML 上的绑定:

<mat-checkbox [disabled]="row.IsVerified" (ngModelChange)="setTrue()"></mat-checkbox>

了解这一点:数据绑定触发更改检测。发生的事情是当你点击复选框时触发变化检测,然后你 运行 一个带有 ngModelChange 的函数来更新变量。

同样,这触发了变化检测,Angular 再次检查表达式,发现它已经改变:它抛出一个 ExpressionChangedAfterItHasBeenCheckedError.

你基本上是在做同样的工作两次,造成了问题。

编辑根据对该答案的评论,解决方案是

<mat-checkbox [checked]="!!row.isVerified" [disabled]="row.IsVerified" (ngModelChange)="setTrue()"></mat-checkbox>