有条件地在Angular 2反应形式

时间:2017-04-19 08:46:22

标签: angular typescript

我是否可以在Angular 2反应形式中有条件地实施验证。我有这个带有3个formControl字段的反应形式,一个是选择,另外两个是名字和姓氏的输入文本。我想根据第一个字段“validateBy”的选择有条件地实现firstname和lastname的验证。如果用户选择'byFirstName',则只应验证firstName。如果用户选择'byLastName',则只应验证lastName。如果用户选择'byBoth',则应验证firstName和lastName。我为此创造了一个plunker。只有byBoth才能验证。

ngOnInit() {
this.myForm = this._fb.group({
  validateBy: ['byFirstName'],
  firstName:  ['', isFirstNameValid(() => (this.validateBy === 'byFirstName' || this.validateBy === 'byBoth'),
                     Validators.required)],
  lastName: ['', isLastNameValid(() => (this.validateBy === 'byLastName' || this.validateBy === 'byBoth'),
                     Validators.required)],
}); 

https://plnkr.co/edit/X0zOGf?p=preview

3 个答案:

答案 0 :(得分:6)

问题是你的代码只计算一次表达式 - 创建FormGroup时。您需要通过创建自定义验证器使其动态化,该验证器将在每次调用时评估表达式:

this.personForm= this.fb.group({
  firstName: ['', Validators.required];
  lastName:  [
    '', 
    conditionalValidator(
      (() => this.isValidationForLastName === true),
      Validators.required
    )
  ]
});

function conditionalValidator(condition: (() => boolean), validator: ValidatorFn): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} => {
    if (! condition()) {
      return null;
    }
    return validator(control);
  }
}

答案 1 :(得分:6)

另一种做法就是这样。似乎适用于plunker

  ngOnInit() {
    this.myForm = this._fb.group({
      validateBy: ['byFirstName'],
      firstName:  [''],
      lastName: [''],
    });

    this.myForm.get('validateBy').valueChanges.subscribe(
        (validateBy : string) => {
          if (validateBy === 'byFirstName' || validateBy === 'byBoth') {
            this.myForm.get('firstName').setValidators([Validators.required]);
            this.myForm.get('firstName').updateValueAndValidity();
          }
          if (validateBy === 'byLastName' || validateBy == 'byBoth') {
            this.myForm.get('lastName').setValidators([Validators.required]);
            this.myForm.get('lastName').updateValueAndValidity();
          }

        };
      )
  }

答案 2 :(得分:0)

我为此专门制作了library

您的解决方案可能类似于:

constructor(private cv: ConditionallyValidateService, private fb: FormBuilder) {}

ngOnInit() {
    this.myForm = this._fb.group({
        validateBy: ['byFirstName'],
        firstName:  [''],
        lastName: [''],
     });

    cv.validate(this.myForm, 'firstName')
        .using(Validators.required)
        .when('validateBy')
        .is('byFirstName')

    cv.validate(this.myForm, 'lastName')
        .using(Validators.required)
        .when('validateBy')
        .is('byLastName')

    cv.validate(this.myForm, 'firstName', 'lastName')
        .using(Validators.required)
        .when('validateBy')
        .is('byBoth')

}