首页 > 解决方案 > 输入类型 = 数字验证在角度中无法正常工作

问题描述

我希望 input type=number 接受 0.1 和 0.9 之间的十进制数字(点后只有一个十进制数字,例如:0.11 不允许),还有数字 1。
我试图从指令中限制它。似乎该指令有效,但随后我按下提交按钮,表单控件的值不正确。
例如,如果我输入 0.11,则输入中显示 0.1,但表单控件的值为 0.11。
如果我键入一个从 1 到 9 的数字,则输入为空,但表单控件具有该数字的值。
这是一个 stackblitz 链接:https ://stackblitz.com/edit/angular-ivy-xa5g8v?file=src%2Fapp%2Fapp.component.ts

标签: angularangular-reactive-formsangular-directiveangular-forms

解决方案


发生这种情况是因为您正在更新 DOM 而不是表单模型。最简单和常见的方法之一是从指令发出事件并在事件处理程序中更新表单模型,如下所示,

修改指令

import { Component, Output, EventEmitter } from "@angular/core";
//other import statements

@Directive({
  selector: "[appLimitDecimal]"
})
export class LimitDecimalDirective {
  @Output()
  purgedValue: EventEmitter<any> = new EventEmitter();
  @HostListener("input", ["$event"])
  changes(evt: any) {
    const removeLastChar = evt.target.value.substring(
      0,
      evt.target.value.length - 1
    );
    // if decimal number length is bigger than 3
    if (evt.target.value.length > 3) {
      console.log("fromDirective", removeLastChar);
    }
    // decimal numbers from 0.1 to 0.9 and 1
    // remove last character if does not match regex
    if (!/^(?:0(?:\.[1-9])?|1)$/.test(evt.target.value)) {
      // evt.target.value = removeLastChar;
      this.purgedValue.emit(removeLastChar);
    }
  }
}

修改输入元素

<input
  type="number"
  formControlName="numberInp"
   appLimitDecimal
  (purgedValue)="setValue($event)"
  min="0.1"
  max="1.0"
  step="0.1"
 />

最后,在 app.component.ts 中添加如下回调方法

  setValue(val) {
    this.f.patchValue({ numberInp: val });
  }

推荐阅读