【问题标题】:Input type number step validation - Custom form validation输入类型编号步骤验证 - 自定义表单验证
【发布时间】:2020-06-14 12:10:38
【问题描述】:

我有一个使用响应式表单的 Angular 应用程序。我的输入字段之一是数字类型,我使用 step 指令来确定有效值,如下所示:

steps = 0.25
myForm: FormGroup

constructor(private fb: FormBuilder) {
  myForm = this.fb.group({
      numberControl: new FormControl(null)
  });

<input type="number" step="{{steps}}" formControlName="numberControl">

可以根据应用程序的其他输入来更改 step 属性,但为简单起见,我没有将其包含在此示例中。我的问题是表单始终有效。当我使用输入字段的向上和向下箭头键时,该步骤有效,但我可以手动输入任何值,它仍然有效。

Stackblitz 示例:https://stackblitz.com/edit/angular-rhyeeb

感谢任何帮助!

【问题讨论】:

  • 您的意思是数字输入字段只能通过步进箭头控制,而不是通过键盘控制。我说的对吗?
  • 不,如果我手动输入一个无效步骤的值,我希望表单无效。所以在我的例子中像 0.26
  • 您应该为您的输入字段创建一个自定义验证器。您可以在 google 中找到大量关于此的文章。

标签: angular validation input angular-reactive-forms


【解决方案1】:

默认情况下,数字输入字段不会验证用户手动输入的数字是否可以被计步器整除。如果您想要这样的功能,那么您必须实现一个非常简单的自定义验证器。

您所要做的就是创建一个函数来验证数字输入字段,然后将新创建的验证器包含在 FormControl 对象的 Validators 数组中。当您的自定义验证测试通过时,您的验证器函数应该返回 null 值,或者返回详细说明失败原因的键值对映射。

找到以下代码 sn-p 演示使用自定义验证器来检查当前输入值是否是有效步骤。

export class AppComponent implements OnInit {
  steps = 0.25;
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      numberControl: new FormControl(null, [
        Validators.required,
        this.validateNumField.bind(this)
      ])
    });

    this.myForm.valueChanges.subscribe(_ => {
      if (!this.myForm.valid) {
        console.log('err msg -> ', this.myForm.get("numberControl").errors);
      }
    });
  }

  validateNumField(control: AbstractControl): { [key: string]: any } {
    let rem = control.value && Number.parseFloat(control.value) % this.steps;
    // console.log(rem);

    /**
    * If the remainder is not 0 then user has entered an invalid value
    */
    return rem ? { error: "Not a valid step" } : null;
  }
}

现在,如果不是有效步骤,您的提交按钮将不起作用。如果您想使用this.myForm.get("numberControl").errors 属性,可以继续在模板上显示错误消息。

您可以在 stackblitz here 中找到一个工作示例。有关自定义验证的更多信息,请访问Angular docs

编辑:更新答案以捕捉步数值的变化。

【讨论】:

  • 我假设 step 属性会默认验证输入。谢谢!
【解决方案2】:

您需要自己实现自定义验证。

import { AbstractControl } from '@angular/forms';

function stepsValidator(control: AbstractControl) {
    if (!control.value || control.value % this.steps !== 0) {
        return { error: true };
    }
    return null;
}

然后在你的 formControl 声明中

myForm = this.fb.group({
    numberControl: new FormControl(null, this.stepsValidator.bind(this))
});

您必须使用绑定函数,因为自定义验证器的作用域与其所在的组件不同。

【讨论】:

    猜你喜欢
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2018-08-28
    相关资源
    最近更新 更多