代码之家  ›  专栏  ›  技术社区  ›  Chris Halcrow

角度-将自定义验证器分配给FormGroup

  •  6
  • Chris Halcrow  · 技术社区  · 7 年前

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

    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;
          }
    }
    

    不过,我有一种情况需要添加自定义验证器 之后 我已经实例化了FormGroup,所以我在实例化之后尝试这样做 myForm ,而不是在窗体实例化时添加验证程序:

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

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

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

    如何将验证器分配给 FormGroup 所以 formGroup 将作为参数传递给 comparisonValidator 功能?

    更新 -我添加了一行显示我在做什么 setErrors 在我的 比较验证器 ,以便更清楚地了解我是如何设置验证错误的。

    4 回复  |  直到 6 年前
        1
  •  8
  •   Anuradha Gunasekara    7 年前

    我创造了一个 stackblitz 看一看。

    在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;
        };
     }
    }
    

    在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>
    
        2
  •  2
  •   Shadab Faiz    7 年前

    对于在实例化FormGroup之后设置任何验证程序(预定义的或自定义的),需要使用 设置验证程序() FormGroup的方法。 例如:

      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.

        3
  •  1
  •   Chris Halcrow    7 年前

    感谢@anuradha gunasekara-他的回答是最正确和最完整的解决方案。我的错误的“快速修复”是添加返回类型 any 在验证器上。我仍然可以将自定义验证器分配给 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 });
          }
    }
    
        4
  •  -1
  •   Coolweb    6 年前

    以上的解决方案似乎有效,但这不是一个好方法,请阅读以下内容 enter link description here