wake-up-neo.com

Angular - Zuweisen eines benutzerdefinierten Validators zu einer FormGroup

Ich muss einer FormGroup einen benutzerdefinierten Validator zuweisen. Ich kann dies zum Zeitpunkt der Erstellung der FormGroup folgendermaßen tun:

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

Ich habe jedoch eine Situation, in der ich den benutzerdefinierten Validator hinzufügen muss, nachdem die FormGroup instanziiert wurde. Daher versuche ich dies nach dem Instanziieren von myForm, anstatt den Validator beim Instanziieren des Formulars hinzuzufügen:

let myForm : FormGroup;

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

this.myForm.validator = this.comparisonValidator;

Dies gibt mir einen Compilerfehler:

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

Wie ordne ich meinem FormGroup einen Prüfer zu, damit der formGroup als Argument an meine comparisonValidator - Funktion übergeben wird?

pdate - Ich habe in meinem setErrors eine Zeile eingefügt, die angibt, wo ich eine comparisonValidator mache, um zu verdeutlichen, wie ich eine setze Validierungsfehler.

9
Chris Halcrow

Ich habe ein stackblitz erstellt.

In der Datei 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 der Datei 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>
12

Zum Festlegen von (vordefinierten oder benutzerdefinierten) Validatoren nach dem Instanziieren der formGroup müssen Sie die setValiators () -Methode von FormGroup verwenden. Zum Beispiel:

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

Du kannst hier spielen.

3
Shadab Faiz

Dank @Anuradha Gunasekara - seine Antwort ist die richtigste und vollständigste Lösung. Eine 'schnelle Lösung' für meinen Fehler bestand darin, dem Validator den Rückgabetyp any hinzuzufügen. Ich kann den benutzerdefinierten Validator weiterhin dem FormGroup zuweisen, und der FormGroup wird implizit als Argument an meinen benutzerdefinierten Validator übergeben. Dieser Code funktioniert:

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 });
      }
}
3
Chris Halcrow