在formgroup上设置验证器

时间:2018-01-20 15:33:29

标签: angular validation typescript angular-components angular-reactive-forms

我查看了多个问题,所有答案都是在表单组上设置验证器。我知道如何使用表单构建器,如下所示。

 this.userForm = this.fb.group({
  id: '',
  firstName: ['', [Validators.required]],
  lastName: ['', [Validators.required]],
  email: ['', [Validators.required]],
  phoneNumber: ['', [Validators.required]],
  jobTitle: ['', [Validators.required]],
  team: ['', [Validators.required]],
  passwords: this.fb.group({
    password: '',
    confirmPassword: ''
  },{
    validator: Validators.compose([PasswordValidators.MatchPassword, PasswordValidators.PasswordRequirements])
  }),
  userValues: this.fb.array([])
});

现在我的组件有两种模式,添加和编辑。如果模式是添加,则密码控件应使用所需的验证器。我检查模式,如果它不在编辑模式,我想更新密码表格组上的验证器,以包括所需的验证器。我在ngInit事件中尝试了这个,如下所示。

 // if not edit mode then the password fields are required, so we overwrite the default validators.
if(!this.isEditMode)
{
  console.log("user form mode: " + this.isEditMode)
  const passwordForm = <FormGroup>this.userForm.controls['passwords'];

   // try to set the validators on the form group as a whole.
  passwordForm.setValidators([PasswordValidators.MatchPassword, PasswordValidators.PasswordRequirements, Validators.required]);
  // try to set the password on the individual control.
  passwordForm.controls['password'].setValidators([PasswordValidators.MatchPassword, PasswordValidators.PasswordRequirements, Validators.required]);

}

现在我尝试更新表单组中的验证器的第一次尝试没有任何区别。我们更新单个表单控件的第二次尝试会导致我的验证程序抛出异常。因此,我可以将其应用于表单组,而无需更改验证程序的工作方式。验证器可以在下面看到。

import { AbstractControl, ValidatorFn } from '@angular/forms';

export class PasswordValidators {

    static MatchPassword(AC: AbstractControl){
        let password = AC.get('password').value; // to get value in input tag
        let confirmPassword = AC.get('confirmPassword').value; // to get value in input tag

         if(!password || password == "")
         {
             return null;
         }

         if(password != confirmPassword) {
             AC.get('confirmPassword').setErrors( {MatchPassword: true} );
         } else {
             return null;
         }
    }

    // Ensures the password meets the minimum standard. Password should be at least 8 char, contain one numeric, one character, and one special character.
    static PasswordRequirements(AC: AbstractControl) {
        let password = AC.get('password').value;

        if(!password || password == "")
        {
            return null;
        }

        if(password != password.match("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$")) {
            AC.get('password').setErrors({PasswordRequirements: true})
        } else {
            return null;
        }

    }
}

关于如何实现这一目标的任何建议都会很棒。欢呼声。

1 个答案:

答案 0 :(得分:0)

要解决这个问题,因为我知道我的表格处于什么状态,我的评论中提到的JB Nizet只有两种不同的表单定义。

它感觉像是最干净的解决方案,但对于这个用例,它可以工作。

if(!this.isEditMode) {
  this.userForm = this.fb.group({
    id: '',
    firstName: ['', [Validators.required]],
    lastName: ['', [Validators.required]],
    email: ['', [Validators.required]],
    phoneNumber: ['', [Validators.required]],
    jobTitle: ['', [Validators.required]],
    team: ['', [Validators.required]],
    passwords: this.fb.group({
      password:  ['', Validators.required],
      confirmPassword:  ['', Validators.required]
    },{
      validator: Validators.compose([PasswordValidators.MatchPassword, PasswordValidators.PasswordRequirements])
    }),
    userValues: this.fb.array([]),
    roles: []
  });
} else { 
  this.userForm = this.fb.group({
    id: '',
    firstName: ['', [Validators.required]],
    lastName: ['', [Validators.required]],
    email: ['', [Validators.required]],
    phoneNumber: ['', [Validators.required]],
    jobTitle: ['', [Validators.required]],
    team: ['', [Validators.required]],
    passwords: this.fb.group({
      password: '',
      confirmPassword: ''
    },{
      validator: Validators.compose([PasswordValidators.MatchPassword, PasswordValidators.PasswordRequirements])
    }),
    userValues: this.fb.array([]),
    roles: []
  });
}