несколько настраиваемых валидаторов в реактивной форме angular 2

У меня есть два пользовательских validator в reactive form, я вызываю функцию ниже, чтобы создать форму в конструкторе компонентов:

private createForm(): void {
this.passwordUpdateForm = this.formBuilder.group({
    newpassword : [null, Validators.required],
    passwordconfirm: [null, Validators.required]
},
{
    validator: [PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule] // validation method

});

}

PasswordValidation - это класс с двумя функциями, как показано ниже.

    export class PasswordValidation {

     public  static PasswordMatch(control: AbstractControl) {
        let password = control.get('newpassword'); // to get value in input tag
        if(password){
            let confirmPassword = control.get('passwordconfirm').value; // to get value in input tag
            if (password.value !== confirmPassword) {
                control.get('passwordconfirm').setErrors({ ['passwordmatch'] : true});
            }else {
                return null;
            }
        }
    }

    public static PasswordRule(control: AbstractControl) {
        let password = control.get('newpassword').value; // to get value in input tag
        let pattern = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,64}');               
        if (!pattern.test(password)) {
            control.get('newpassword').setErrors({ ['passwordrule'] : true});
        }else if (password.toLowerCase() === 'something') {
            control.get('newpassword').setErrors({ ['passwordrule'] : true});
        }else {
            return null;
        }
    }
}

каждый пользовательский валидатор отлично работает отдельно, вот так

validator: PasswordValidation.PasswordMatch

или это

validator: PasswordValidation.PasswordRule

но используя их оба в массиве, например

validator: [PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule]

получить ошибку this.validator is not a function и не работает, я понятия не имею, помогите пожалуйста.


comment
Можете ли вы попробовать с Validators.compose() which принимает несколько валидаторов для одного поля.   -  person Niladri    schedule 09.09.2017
comment
Да, используйте compose (): validator: Validators.compose ([[PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule])}   -  person Vega    schedule 09.09.2017
comment
@Vega не работает   -  person Paridokht    schedule 09.09.2017
comment
У вас такая же ошибка или она не проверяется?   -  person Vega    schedule 09.09.2017
comment
@Vega O Работает, спасибо. Ваш комментарий заставил меня проверить это еще раз, мне было так скучно! Спасибо большое   -  person Paridokht    schedule 09.09.2017
comment
Здорово! рад, что это сработало :)   -  person Vega    schedule 09.09.2017


Ответы (1)


лучше использовать Validators.compose([]), который принимает массив валидаторов для использования в конкретном пользовательском элементе управления в группе форм.

например, если вы хотите добавить валидаторы к элементам управления passwordconfirm и newpassword, вы можете сделать это, как показано ниже

private createForm(): void {
this.passwordUpdateForm = this.formBuilder.group({
    newpassword : [null, Validators.compose([Validators.required,PasswordValidation.PasswordRule])],
    passwordconfirm: [null, Validators.compose([Validators.required, PasswordValidation.PasswordMatch])]
});

под капотом вот как выглядит код

group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null): FormGroup {
  const controls = this._reduceControls(controlsConfig);
  const validator: ValidatorFn = isPresent(extra) ? extra['validator'] : null;
  const asyncValidator: AsyncValidatorFn = isPresent(extra) ? extra['asyncValidator'] : null;
  return new FormGroup(controls, validator, asyncValidator);
}

вы можете видеть, что параметр validator на самом деле является типом интерфейса ValidatorFn, который выглядит как показано ниже

interface ValidatorFn { 
  (c: AbstractControl): ValidationErrors|null
}

так что вы можете видеть, что он может принимать любой метод, имеющий указанную выше подпись.

Источник: https://angular.io/api/forms/ValidatorFn.

Проверьте эту ссылку, чтобы узнать больше: https://toddmotto.com/reactive-formgroup-validation-angular-2

person Niladri    schedule 09.09.2017
comment
Я тестировал его, но безуспешно, потому что validators.compose принимает валидароты, которые возвращают observable или promise: / - person Paridokht; 09.09.2017
comment
@ Parid0kht Я думаю, вы говорите об асинхронных валидаторах, но из вашего кода вы используете только статические валидаторы синхронизации. Для валидаторов синхронизации Observable или Promise не требуются. Я обновил свой ответ, объяснив, почему вы не можете передавать валидаторы в виде массива методу formbuilder.group() . - person Niladri; 09.09.2017