首页 > 解决方案 > type=number 的 Angular Reactive Form 控件将在模糊时重新渲染

问题描述

我有一个 Angular(v7) 反应式表单(可能与仅模板表单相同)。<input>with将type="number"重新渲染并在模糊上运行验证。旁边
的错误反馈中有一个值建议按钮,单击该按钮将使用建议值(由异步验证器提供)填充输入。 但是,如果您第一次单击该按钮,则 的模糊将触发整个元素的重新渲染,因此对输入没有影响。您必须再次单击该按钮才能使其工作。<div><input>
<input>

我没有找到任何禁用此重新渲染行为的选项。

演示:stackblitz.com

.ts 文件:

ngOnInit(): void {
    this.newPlanForm = this.formBuilder.group({
      plan_id: [
        {
          value: this.plan.plan_id,
          disabled: !this.plan.insurer_id,
        }, {
          validators: [Validators.required, this.planIdSyntaxValidator.bind(this)],
          asyncValidators: this.planIdDuplicationValidator.bind(this),
          // updateOn: 'blur' // this is my hacky solution. The original problem occours without it
        }
      ],
      ...
    });
}

planIdDuplicationValidator(control: AbstractControl): Observable<ValidationErrors | null> {
    // duplication check
    ...
}

fillInSuggestedPlanId(): void {
    this.form.plan_id.setValue(this.form.plan_id.errors.duplicatePlanId);
}

// convenience getter for easy access to form fields
get form() {
    return this.newPlanForm.controls;
}

HTML:

<form [formGroup]="newPlanForm">
    ...
    <label for="plan_id">Plan ID<sup>*</sup></label>
    <input type="number" class="form-control" id="plan_id" name="plan_id"
           [ngClass]="{ 'is-invalid': form.plan_id.errors }"
           formControlName="plan_id"/>
    <div class="invalid-feedback" *ngIf="form.plan_id.dirty && form.plan_id.errors">
      <p *ngIf="form.plan_id.errors.duplicatePlanId">
        This plan ID is already taken. Next available is
        <a (click)="fillInSuggestedPlanId()" class="btn-link">
          {{suggestedPlanID}}
        </a>
      </p>
    </div>
    ...
</form>

标签: angularreactive-forms

解决方案


请注意input=number 规范中的以下注释

注意: type=number 状态不适用于恰好只包含数字但严格来说不是数字的输入。例如,它不适用于信用卡号或美国邮政编码。确定是否使用 type=number 的一种简单方法是考虑输入控件是否具有旋转框界面(例如,带有“向上”和“向下”箭头)是否有意义。信用卡号的最后一位错了 1 并不是一个小错误,它就像错了每个数字一样。因此,用户使用“向上”和“向下”按钮选择信用卡号是没有意义的。当 spinbox 界面不合适时,type=text 可能是正确的选择(可能带有模式属性)。

我不得不问:为什么不使用 just type=text


推荐阅读