我的 Angular 应用程序遇到问题,在提交表单后,我动态更改表单中选择字段的
required
属性。
evaluations.component.html
<form
novalidate
#form="ngForm"
(ngSubmit)="form.form.valid && onSubmit()">
<div *ngFor="let evaluation of evaluations; index as index">
<select
name="evaluator{{index}}"
id="evaluator{{index}}"
#evaluatorField="ngModel"
[(ngModel)]="evaluatorId"
[required]="isEvaluatorRequired"
[ngClass]="{'is-invalid': form.submitted && evaluatorField.invalid}">
<option *ngFor="let evaluator of evaluators" [ngValue]="evaluator._id">
{{evaluator.name}}
</option>
</select>
...
</div>
<div>
<input type="radio" name="operation" #operation="ngModel" id="operation-suggested" [value]="'APPROVE'"
[(ngModel)]="operation" (ngModelChange)="onOperationChange($event)" required />
<input type="radio" name="operation" #operation="ngModel" id="operation-decline" [value]="'DECLINE'"
[(ngModel)]="operation" (ngModelChange)="onOperationChange($event)" required />
...
</div>
...
<button type="submit" id="save">
Save
</button>
</form>
当操作值发生变化时,isEvaluatorRequired
会随着对 onOperationChange(...)
did 的调用而变化。
evaluations.component.ts
...
onOperationChange(operation: OperationStatus) {
this.isEvaluatorRequired = [OperationStatus.APPROVE,/*...*/].includes(operation);
}
...
当我在提交表单后更改操作值时,就会出现问题,这又会修改
isEvaluatorRequired
值。这会触发以下错误:
ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
Previous value: 'true'. Current value: 'false'. Expression location: EvaluationsComponent.component.
这表明问题出在
isEvaluatorRequired
,这里:[required]="isEvaluatorRequired"
。
我简化了示例,仅分享与该问题相关的元素。我想知道为什么它会给出错误,尽管它正确地改变了行为?
我以为问题出在
[required]
中的绑定,但是,实际上问题就在这里:
[ngClass]="{'is-invalid': form.submitted && formEvaluator.invalid}"
它也有错误的行为。为什么不起作用?
错误消息表明
isEvaluatorRequired
在更改检测运行后发生更改。避免这种情况的一种方法是使用信号或主题和 AsyncPipe:
[required]="isEvaluatorRequired$ | async"
或者您可以在更新后强制进行更改检测
isEvaluatorRequired
:
// ChangeDetectorRef needs to be injected:
private cdr = inject(ChangeDetectorRef);
// After changing isEvaluatorRequired:
this.cdr.detectChanges();