Angular 2中响应式表单中多个自定义验证器

10

我在响应式表单中有两个自定义的验证器,在组件构造函数中调用下面的函数来创建表单:

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,但它并不起作用,我一点头绪也没有,请帮帮我。


你可以尝试使用Validators.compose(),它接受多个验证器来验证一个字段。 - Niladri
1
使用compose():validator: Validators.compose([[PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule])} - Vega
@Vega不起作用 - Paridokht
你遇到了相同的错误还是它没有通过验证? - Vega
2
@Vega O,它正在工作,谢谢。你的评论让我再次检查了它,我太无聊了!非常感谢你。 - Paridokht
太好了!很高兴它起作用了 :) - Vega
1个回答

10

最好使用 Validators.compose([]),该方法接受一个验证器数组,用于在表单组中特定的用户控件上使用。

例如,如果要针对 passwordconfirmnewpassword 控件添加验证器,可以按照以下方式进行操作:

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


我已经测试过了,但是没有成功,因为validators.compose只接受返回observablepromise的验证器 :/ - Paridokht
@Parid0kht,我认为你在谈论异步验证器,但从你的代码中可以看出你只使用了静态同步验证器。对于同步验证器,不需要Observable或Promise。我已经更新了我的答案,并解释了为什么你不能将验证器作为数组传递给formbuilder.group()方法。 - Niladri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接