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

时间:2018-05-16 14:08:44

标签: angular angular-material2 rxjs6

请参阅示例: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'.

我该怎么做才能摆脱错误?

1 个答案:

答案 0 :(得分:0)

您应该删除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>