Angular 类型为number的角度反应型窗体控件将在模糊时重新渲染

Angular 类型为number的角度反应型窗体控件将在模糊时重新渲染,angular,reactive-forms,Angular,Reactive Forms,我有一个角度(v7)反应形式(可能对于仅模板形式相同)。 带有type=“number”的将重新渲染并在模糊上运行验证。 在旁边的错误反馈中有一个值建议按钮,单击该按钮将用建议值(由异步验证器提供)填充输入。 但是,如果第一次单击该按钮,的模糊将触发整个元素的重新渲染,因此不会影响输入。您必须再次单击该按钮才能使其工作 我没有找到任何选项来禁用此重新渲染行为 演示: .ts文件: ngOnInit(): void { this.newPlanForm = this.formBuilder

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

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

演示:

.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;
}
ngOnInit():void{
this.newPlanForm=this.formBuilder.group({
计划编号:[
{
值:this.plan.plan\u id,
已禁用:!this.plan.insurance\u id,
}, {
validators:[validators.required,this.planIdSyntaxValidator.bind(this)],
asyncValidators:this.PlanidReplicationValidator.bind(this),
//updateOn:'blur'//这是我的黑客解决方案。没有它,最初的问题就会出现
}
],
...
});
}
PlanidReplicationValidator(控件:AbstractControl):可观察{
//重复检查
...
}
fillInSuggestedPlanId():无效{
this.form.plan_id.setValue(this.form.plan_id.errors.duplicatePlanId);
}
//方便的getter,便于访问表单字段
获取表单(){
返回this.newPlanForm.controls;
}
HTML:


...
计划ID*

此计划ID已被使用。下一个可用的是
{{suggestedPlanID}}

...
请注意:

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


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

尝试从验证器中删除updateOn:'blur'属性array@Chellappan对不起,这是我的黑客解决方案,事实上,没有它问题就发生了。(顺便说一句,这是控件本身的配置属性,而不是验证程序级别。)请参见我的编辑。请创建一个演示,显示此问题:)@AJT_82添加了演示。请输入除“12345”之外的任何内容,然后单击下面的链接按钮,您将看到有问题的行为。@MylesFong我一定会查看它。不过我刚开始工作,所以我想我需要工作:D希望你能等一等,我会尽我最大的努力帮助你,稍后:)谢谢你,这对这个案子很有意义。但如果还有另一种情况,type=number是正确的,比如数量输入,并且需要一个提示值按钮,就像我的情况一样,该怎么办?
<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>