Javascript Angular - 将自定义验证器分配给 FormGroup

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51094146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:45:19  来源:igfitidea点击:

Angular - assign custom validator to a FormGroup

javascriptangulartypescriptangular-reactive-formsangular-validation

提问by Chris Halcrow

I need to assign a custom validator to a FormGroup. I can do this at the time the FormGroup is created like this:

我需要为 FormGroup 分配一个自定义验证器。我可以在 FormGroup 创建时这样做:

let myForm : FormGroup;

myForm = this.formBuilder.group({
        myControl1: defaultValue,
        myControl2: defaultValue
      }, { validator: this.comparisonValidator })

comparisonValidator(g: FormGroup) {
      if (g.get('myControl1').value > g.get('myControl2'.value)) {
        g.controls['myControl1'].setErrors({ 'value2GreaterThanValue1': true });
        return;
      }
}

I have a situation though where I need to add the custom validator afterI've instantiated the FormGroup, so I'm trying to do this after instantiating myForm, instead of adding the validator when the form is instantiated:

我有一种情况,我需要在实例化 FormGroup添加自定义验证器,所以我尝试在实例化后执行此操作myForm,而不是在实例化表单时添加验证器:

let myForm : FormGroup;

myForm = this.formBuilder.group({
        myControl1: defaultValue,
        myControl2: defaultValue
      })

this.myForm.validator = this.comparisonValidator;

This gives me a compiler error:

这给了我一个编译器错误:

Type '(g: FormGroup) => void' is not assignable to type 'ValidatorFn'.
  Type 'void' is not assignable to type 'ValidationErrors'.

How do I assign a validator to my FormGroupso that the formGroupis passed as the argument to my comparisonValidatorfunction?

如何为 my 分配一个验证器,FormGroup以便将其formGroup作为参数传递给我的comparisonValidator函数?

Update- I've added a line showing where I'm doing a setErrorsin my comparisonValidator, to make it clearer exactly how I'm trying to set a validation error.

更新- 我添加了一行,显示我setErrors在我的comparisonValidator.

回答by Anuradha Gunasekara

I've created a stackblitztake a look.

我创建了一个stackblitz来看看。

In the component.ts file

在 component.ts 文件中

import { Component } from '@angular/core';
import {FormBuilder,FormGroup, ValidationErrors, ValidatorFn} from '@angular/forms'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  myForm: FormGroup;
  defaultValue = 20;

constructor(private formBuilder: FormBuilder) {
  this.myForm = this.formBuilder.group({
        myControl1: this.defaultValue,
        myControl2: this.defaultValue
      });
      debugger
      this.myForm.setValidators(this.comparisonValidator())
}

 public comparisonValidator() : ValidatorFn{
       return (group: FormGroup): ValidationErrors => {
          const control1 = group.controls['myControl1'];
          const control2 = group.controls['myControl2'];
          if (control1.value !== control2.value) {
             control2.setErrors({notEquivalent: true});
          } else {
             control2.setErrors(null);
          }
          return;
    };
 }
}

In the component.html file

在 component.html 文件中

<div>
  <form [formGroup]="myForm">
    <input formControlName="myControl1" type="number">
    <input formControlName="myControl2"  type="number">
    <br>Errors: {{myForm.get('myControl2').errors | json}}
  </form>
</div>

回答by Chris Halcrow

Thanks to @Anuradha Gunasekara - his answer is the most correct and complete solution. A 'quick fix' for my error was just to add a return type of anyon the validator. I can still assign the custom validator to the FormGroup, and the FormGroupwill be passed implicitly as the argument to my custom validator. This code will work:

感谢@Anuradha Gunasekara - 他的答案是最正确和最完整的解决方案。我的错误的“快速修复”只是any在验证器上添加返回类型。我仍然可以将自定义验证器分配给FormGroup,并且FormGroup将作为参数隐式传递给我的自定义验证器。此代码将起作用:

let myForm : FormGroup;

myForm = this.formBuilder.group({
           myControl1: defaultValue,
           myControl2: defaultValue
         })

this.myForm.validator = this.comparisonValidator;

comparisonValidator(g: FormGroup) : any {
      if (g.get('myControl1').value > g.get('myControl2'.value)) {
        g.controls['myControl1'].setErrors({ 'value2GreaterThanValue1': true });
      }
}

回答by Shadab Faiz

For setting any validators (predefined or customs) after the instantiating the formGroup, you will need to use the setValiators()method of FormGroup. For Ex:

要在实例化 formGroup 之后设置任何验证器(预定义或自定义),您需要使用FormGroup 的 setValiators()方法。例如:

  let myFormGroup = this.    _fb.group({
      control1: new FormControl('1', [])
    });
  myFormGroup.setValidators(this.customValidators());
  customValidators(): ValidatorFn {
   let myFun = (cc: FormGroup): ValidationErrors => {
     if(cc.valid) return null;
     else return {something: 'someError'};
   };
   return myFun;
  }

You can play here.

你可以在这里玩。