W Angular, jak dodać Validator do FormControl po utworzeniu kontroli?

89

Mamy komponent, który ma dynamicznie budowaną formę. Kod dodający kontrolkę z walidatorami może wyglądać następująco:

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

Ale powiedzmy, że chcę dodać drugi walidator później . Jak możemy to osiągnąć? Nie możemy znaleźć żadnej dokumentacji na ten temat w Internecie. Znalazłem chociaż w kontrolkach formularza jest setValidators

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

ale nie jest jasne, jak dodać nowy lub niestandardowy walidator.

melegant
źródło

Odpowiedzi:

119

Po prostu przekazujesz FormControl tablicę walidatorów.

Oto przykład pokazujący, jak można dodać walidatory do istniejącego FormControl:

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

Uwaga: spowoduje to zresetowanie wszystkich istniejących walidatorów dodanych podczas tworzenia FormControl.

Andy-Delosdos
źródło
5
ha ... czasami patrzysz na coś tak długo, że najlepiej jest po prostu odejść. DZIĘKUJĘ CI!!
melegant
1
Czy istnieje sposób na usunięcie weryfikacji
Abhijith ss
7
jakikolwiek sposób, aby to zrobić bez zastępowania starych? lub jakikolwiek sposób na dołączenie nowych?
danday74
1
@ danday74, sprawdź odpowiedź Eduarda Voida na dole tego pytania. Należy zaakceptować odpowiedź imo. Wyjaśnia, jak zrobić to, co musisz wiedzieć, a ja też musiałem umieć to zrobić.
Chris
8
Musiałem również wywołać .updateValueAndValidity()kontrolę formularza po ustawieniu nowych walidatorów.
Keeleon,
91

Aby dodać do tego, co opublikował @Delosdos.

Ustaw walidator dla kontrolki w FormGroup: this.myForm.controls['controlName'].setValidators([Validators.required])

Usuń walidator z kontrolki w FormGroup: this.myForm.controls['controlName'].clearValidators()

Zaktualizuj FormGroup po uruchomieniu jednej z powyższych linii. this.myForm.controls['controlName'].updateValueAndValidity()

To niesamowity sposób na programowe ustawianie walidacji formularza.

shammelburg
źródło
2
Dla mnie działało bez ostatniej linii, jestem prawie pewien, że nowe wersje Angulara aktualizują teraz ważność formularza samodzielnie. Ale dzięki za opowiedzenie nam o updateValueAndValiditymetodzie, może się kiedyś przydać!
Nino Filiu
@NinoFiliu updateValueAndValidityjest nadal używany do sprawdzania poprawności i nie jest obsługiwany inaczej w nowszych wersjach Angular. To, co się dzieje, setValidatorsaktualizuje walidatory, ale nie uruchamia sprawdzania poprawności, a następnie służy updateValueAndValiditydo przeprowadzania walidacji. Musisz ustawić walidatory w punkcie, w którym wykrywanie zmian zajmie się tym za Ciebie, ale przekonasz się, że użycie updateValueAndValidityw grupie lub kontrolce zależy od tego, który walidator właśnie ustawiłeś jako kluczowy - github.com/angular/angular/issues/19622#issuecomment- 341547884 .
mtpultz
4
Jestem na Angular 6 i nie mogę tego zrobić bez updateValueAndValidity. Dzięki @shammelburg!
Oli Crt,
1
Na Angular 7 i dla mnie też nie zadziałałoby bez ostatniej linii aktualizacji.
David Findlay
Tak. Działa bez updateValueAndValidity(), ale w niektórych przypadkach nie. jeśli dodałeś updateValueAndValidity()po setValidators()To natychmiast wpłynie na zmiany związane z kontrolą . Dlatego lepiej jest dodać updateValueAndValidity () `.
Jamith NImantha
78

Jeśli używasz reactiveFormModule i masz formGroup zdefiniowaną w ten sposób:

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

niż jesteś w stanie dodać nowy walidator ( i zachować stare ) do FormControl w ten sposób:

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 zwraca walidator kompozycji zawierający wszystkie wcześniej zdefiniowane walidatory.

Eduard Void
źródło
13
Imo to powinna być akceptowana odpowiedź. Pokazuje, jak dodawać walidatory, takie jak żądanie OP, ale także pokazuje, jak zachować wcześniej ustawione walidatory; co było pierwszą rzeczą, którą wyszukałem w Google po przeczytaniu zaakceptowanej odpowiedzi, ponieważ nie chciałem nadpisywać niektórych walidatorów, które już miałem, ale nadal potrzebowałem programowo dodać kolejne. Dziękuję za tę odpowiedź @Eduard Void
Chris
3
Zgadzam się z moim poprzednikiem. Pytanie brzmiało, jak dodać nowy walidator do formularza kontrolnego, a nie jak go zastąpić .
Plusce
6
Udało mi control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);się obejść surowe kontrole zerowe
William Lohan
3

Myślę, że wybrana odpowiedź jest nieprawidłowa, ponieważ pierwotne pytanie brzmi: „jak dodać nowy walidator po utworzeniu formControl”.

O ile wiem, to niemożliwe. Jedyne, co możesz zrobić, to dynamicznie utworzyć tablicę walidatorów.

Jednak brakuje nam funkcji addValidator (), która nie przesłania walidatorów już dodanych do formControl. Jeśli ktoś ma odpowiedź na to wymaganie, byłoby miło zostać opublikowanym tutaj.

user2992476
źródło
1
Można by pomyśleć, control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);że zadziała.
William Lohan
2
Zobacz odpowiedź @Eduard Void stackoverflow.com/a/53276815/6656422
William Lohan
3

Oprócz odpowiedzi Eduarda Voida, oto addValidatorsmetoda:

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

Za jego pomocą możesz dynamicznie ustawiać walidatory:

some_form_control.addValidators([ first_validator, second_validator ]);
some_form_control.addValidators([ third_validator ]);
lucifer63
źródło