У Angular, як додати Validator до FormControl після створення елемента керування?


84

У нас є компонент, який має динамічно побудовану форму. Код для додавання елемента керування за допомогою валідаторів може виглядати так:

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

Але скажімо, що я хочу додати 2-й Валідатор пізніше . Як ми можемо досягти цього? Ми не можемо знайти жодної документації щодо цього в Інтернеті. Я знайшов, хоча в елементах керування формою є setValidators

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

але незрозуміло, як додати новий або спеціальний валідатор.

Відповіді:


109

Ви просто передаєте FormControl масив валідаторів.

Ось приклад, що показує, як можна додати валідатори до існуючого FormControl:

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

Зверніть увагу, що це призведе до скидання всіх існуючих валідаторів, які ви додали під час створення FormControl.


5
ха ... іноді ти так довго дивишся на щось, що найкраще просто відійти. ДЯКУЮ!!
melegant

1
Чи є спосіб скасувати перевірку
Abhijith ss

7
будь-який спосіб зробити це, не замінюючи старі? чи будь-яким способом додати нові?
danday74

1
@ danday74, перегляньте відповідь Едуарда Войда внизу цього запитання. Слід прийняти відповідь imo. Він пояснює, як робити те, що вам потрібно знати, що мені також потрібно було знати.
Кріс

6
Мені довелося також зателефонувати .updateValueAndValidity()до контролю форми після встановлення нових валідаторів.
Keeleon

82

Щоб додати до того, що опублікував @Delosdos.

Встановіть валідатор для елемента керування в FormGroup: this.myForm.controls['controlName'].setValidators([Validators.required])

Видаліть валідатор із елемента керування у групі форм: this.myForm.controls['controlName'].clearValidators()

Оновіть FormGroup після запуску будь-якого з наведених рядків. this.myForm.controls['controlName'].updateValueAndValidity()

Це дивовижний спосіб програмно встановити перевірку вашої форми.


1
Для мене це працювало без останнього рядка, я впевнений, що нові версії Angular зараз самі по собі оновлюють дію форми. Але спасибі, що повідомили нам про updateValueAndValidityметод, може колись стати в нагоді!
Ніно Філіу

@NinoFiliu updateValueAndValidityвсе ще використовується для здійснення перевірки і не обробляється по-іншому в нових версіях Angular. Те, що відбувається, setValidatorsоновлює валідатори, але не запускає перевірку перевірки, а потім ви використовуєте updateValueAndValidityдля виконання перевірки. Ви повинні встановлювати валідатори в точці, де виявлення змін обробляє це для вас, але ви знайдете використання updateValueAndValidityв групі або елементі керування залежно від того, який валідатор ви щойно встановили - github.com/angular/angular/issues/19622#issuecomment- 341547884 .
mtpultz

4
Я на Angular 6 і не можу змусити це працювати без updateValueAndValidity. Дякую @shammelburg!
Олі Крт

1
На Angular 7 він також не працював би для мене без останнього рядка оновлення.
Девід Фіндлі

Так. Це працює без updateValueAndValidity(), але в деяких випадках це не так. якщо ви додали updateValueAndValidity()після setValidators()Це негайно вплине на зміни, пов'язані з контролем . Тож краще додати updateValueAndValidity () `.
Джаміт Німанта,

73

Якщо ви використовуєте reactiveFormModule і форму formGroup визначаєте так:

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

ніж ви можете додати новий валідатор ( і зберегти старий ) до FormControl за допомогою цього підходу:

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 повертає валідатор складання, що містить усі визначені раніше валідатори.


13
Імо, це має бути прийнятою відповіддю. Він демонструє, як додати валідатори, як запитується OP, а також показує, як зберегти раніше встановлені валідатори; що було першим, що я погуглив, як це зробити після прочитання прийнятої відповіді, тому що я не хотів перезаписувати деякі валідатори, які вже мав, але все одно потребував програмного додавання додаткових. Дякую за цю відповідь @Eduard Void
Chris

3
Я згоден зі своїм попередником. Питання полягало в тому, як додати новий валідатор до контрольної форми, а не як замінити його.
Плюс

5
Я мав control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);обійти суворі перевірки на нуль
Вільям Лохан

3

Я вважаю, що обрана відповідь невірна, оскільки вихідне запитання - "як додати новий валідатор після створення формиControl".

Наскільки я знаю, це неможливо. Єдине, що ви можете зробити, це створити масив валідаторів динамічно.

Але те, чого нам не вистачає, - це мати функцію addValidator (), яка не замінює валідатори, вже додані до formControl. Якщо хтось має відповідь на цю вимогу, було б непогано розмістити тут.


1
control.setValidators(control.validator ? [ control.validator, Validators.email ] : Validators.email);Можна подумати, що це спрацює.
Вільям Лохан,

2
Знайомства @Eduard Порожнечею сек відповідь stackoverflow.com/a/53276815/6656422
Вільям Лохан

3

Окрім відповіді Едуарда Войда, ось addValidatorsметод:

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

З його допомогою ви можете динамічно встановлювати валідатори:

some_form_control.addValidators([ first_validator, second_validator ]);
some_form_control.addValidators([ third_validator ]);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.