在 Angular 中动态更改选择字段的验证

问题描述 投票:0回答:1

我的 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}"

它也有错误的行为。为什么不起作用?

angular forms validation required ng-class
1个回答
0
投票

错误消息表明

isEvaluatorRequired
在更改检测运行后发生更改。避免这种情况的一种方法是使用信号或主题和 AsyncPipe:

[required]="isEvaluatorRequired$ | async"

或者您可以在更新后强制进行更改检测

isEvaluatorRequired
:

// ChangeDetectorRef needs to be injected:
private cdr = inject(ChangeDetectorRef);

// After changing isEvaluatorRequired:
this.cdr.detectChanges();
© www.soinside.com 2019 - 2024. All rights reserved.