Wie füge ich in Angular Validator zu FormControl hinzu, nachdem das Steuerelement erstellt wurde?

84

Wir haben eine Komponente, die eine dynamisch aufgebaute Form hat. Der Code zum Hinzufügen eines Steuerelements mit Validatoren könnte folgendermaßen aussehen:

var c = new FormControl('', Validators.required);

Angenommen, ich möchte später den 2. Validator hinzufügen . Wie können wir das erreichen? Wir können online keine Dokumentation dazu finden. Ich habe jedoch festgestellt, dass es in den Formularsteuerelementen setValidators gibt

this.form.controls["firstName"].setValidators 

Es ist jedoch nicht klar, wie ein neuer oder benutzerdefinierter Validator hinzugefügt werden soll.

melegant
quelle

Antworten:

109

Sie übergeben dem FormControl einfach ein Array von Validatoren.

Hier ist ein Beispiel, das zeigt, wie Sie einem vorhandenen FormControl Validatoren hinzufügen können:

this.form.controls["firstName"].setValidators([Validators.minLength(1), Validators.maxLength(30)]);

Beachten Sie, dass dadurch alle vorhandenen Validatoren zurückgesetzt werden, die Sie beim Erstellen des FormControl hinzugefügt haben.

Andy-Delosdos
quelle
5
ha ... manchmal schaut man sich etwas so lange an, dass es am besten ist, einfach wegzugehen. VIELEN DANK!!
Melegant
1
Gibt es eine Möglichkeit, die Validierung zu entfernen
Abhijith ss
7
Wie kann man das tun, ohne die alten zu überschreiben? oder eine Möglichkeit, die neuen anzuhängen?
danday74
1
@ danday74, lesen Sie die Antwort von Eduard Void am Ende dieser Frage. Sollte akzeptiert werden, antworte imo. Er erklärt, wie man das macht, was man wissen muss, was ich auch wissen muss.
Chris
6
Ich musste auch .updateValueAndValidity()die Formularsteuerung aufrufen , nachdem ich die neuen Validatoren eingestellt hatte.
Keeleon
82

Hinzufügen zu dem, was @Delosdos gepostet hat.

Legen Sie einen Validator für ein Steuerelement fest in FormGroup: this.myForm.controls['controlName'].setValidators([Validators.required])

Entfernen Sie den Validator aus dem Steuerelement in der FormGroup: this.myForm.controls['controlName'].clearValidators()

Aktualisieren Sie die FormGroup, sobald Sie eine der oben genannten Zeilen ausgeführt haben. this.myForm.controls['controlName'].updateValueAndValidity()

Dies ist eine erstaunliche Möglichkeit, Ihre Formularvalidierung programmgesteuert festzulegen.

Shammelburg
quelle
1
Bei mir hat es ohne die letzte Zeile funktioniert. Ich bin mir ziemlich sicher, dass neue Versionen von Angular die Gültigkeit des Formulars jetzt selbst aktualisieren. Aber danke, dass Sie uns von der updateValueAndValidityMethode erzählt haben , könnte eines Tages nützlich sein!
Nino Filiu
@NinoFiliu updateValueAndValiditywird weiterhin zur Durchführung der Validierung verwendet und in neueren Versionen von Angular nicht anders behandelt. Was passiert, ist, setValidatorsdie Validatoren zu aktualisieren, aber keine Validierungsprüfung updateValueAndValiditydurchzuführen , und dann verwenden Sie , um die Validierung durchzuführen. Sie müssen die Validatoren an einem Punkt einstellen, an dem die Änderungserkennung dies für Sie erledigt. Die Verwendung updateValueAndValidityin der Gruppe oder im Steuerelement hängt jedoch davon ab, welchen Validator Sie gerade als entscheidend festgelegt haben - github.com/angular/angular/issues/19622#issuecomment- 341547884 .
Mtpultz
4
Ich bin auf Angular 6 und könnte es ohne das nicht zum Laufen bringen updateValueAndValidity. Danke @shammelburg!
Oli Crt
1
Auf Angular 7 und es würde auch ohne die letzte Update-Zeile für mich nicht funktionieren.
David Findlay
Ja. Es funktioniert ohne updateValueAndValidity(), aber in einigen Fällen nicht. Wenn Sie updateValueAndValidity()nach hinzugefügt haben, setValidators()wirkt sich dies sofort auf die Änderungen in Bezug auf die Steuerung aus . Es ist also besser, updateValueAndValidity () `hinzuzufügen.
Jamith NImantha
72

Wenn Sie reactiveFormModule verwenden und formGroup wie folgt definiert haben:

public exampleForm = new FormGroup({
        name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]),
        email: new FormControl('[email protected]', [Validators.required, Validators.maxLength(50)]),
        age: new FormControl(45, [Validators.min(18), Validators.max(65)])
});

Dann können Sie FormControl mit diesem Ansatz einen neuen Validator hinzufügen ( und alte behalten ):

this.exampleForm.get('age').setValidators([
        Validators.pattern('^[0-9]*$'),
        this.exampleForm.get('age').validator
]);
this.exampleForm.get('email').setValidators([
        Validators.email,
        this.exampleForm.get('email').validator
]);

FormControl.validator gibt einen Compose-Validator zurück, der alle zuvor definierten Validatoren enthält.

Eduard Void
quelle
13
Imo sollte dies die akzeptierte Antwort sein. Es zeigt, wie Sie Validatoren wie das angeforderte OP hinzufügen, aber auch, wie Sie zuvor festgelegte Validatoren beibehalten. Das war das erste, was ich gegoogelt habe, nachdem ich die akzeptierte Antwort gelesen hatte, weil ich einige bereits vorhandene Validatoren nicht überschreiben wollte, aber dennoch programmgesteuert zusätzliche hinzufügen musste. Vielen Dank für diese Antwort @Eduard Void
Chris
3
Ich stimme meinem Vorgänger zu. Die Frage war, wie man einen neuen Validator zum Kontrollformular hinzufügt und nicht wie man ihn ersetzt.
Plusce
5
Ich habe es getan control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);, um strenge Nullprüfungen zu umgehen
William Lohan
3

Ich denke, die ausgewählte Antwort ist nicht korrekt, da die ursprüngliche Frage lautet "Hinzufügen eines neuen Validators nach dem Erstellen des formControl".

Soweit ich weiß, ist das nicht möglich. Das einzige, was Sie tun können, ist, das Array der Validatoren dynamisch zu erstellen.

Was wir jedoch vermissen, ist eine Funktion addValidator (), um die bereits zum formControl hinzugefügten Validatoren nicht zu überschreiben. Wenn jemand eine Antwort auf diese Anforderung hat, wäre es schön, hier gepostet zu werden.

user2992476
quelle
1
Sie würden denken, control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);würde funktionieren.
William Lohan
2
Siehe @Eduard Void 's Antwort stackoverflow.com/a/53276815/6656422
William Lohan
3

Zusätzlich zur Antwort von Eduard Void gibt es hier die addValidatorsMethode:

declare module '@angular/forms' {
  interface FormControl {
    addValidators(validators: ValidatorFn[]): void;
  }
}

FormControl.prototype.addValidators = function(this: FormControl, validators: ValidatorFn[]) {
  if (!validators || !validators.length) {
    return;
  }

  this.clearValidators();
  this.setValidators( this.validator ? [ this.validator, ...validators ] : validators );
};

Mit ihm können Sie Validatoren dynamisch einstellen:

some_form_control.addValidators([ first_validator, second_validator ]);
some_form_control.addValidators([ third_validator ]);
lucifer63
quelle