Angular 5 根据另一个字段的值有条件地验证字段

问题描述 投票:0回答:2

如何根据另一个字段的值有条件地验证一个字段?这是我尝试过的,但似乎不起作用

this.PDform = _formbuilder.group({
    [...]
    'intlNumber': ['',this.nationality == 'Abroad' ? Validators.compose([Validators.pattern(this.phoneNumberExp), Validators.maxLength(14), Validators.minLength(11), Validators.required]) : Validators ]
    [...]
})
angular angular5 angular-reactive-forms angular-forms angular-validation
2个回答
15
投票

当另一个表单控件的值发生更改时,您可以通过订阅表单控件实例提供的

valueChanges
observable 来更改表单控件的验证器:

const control1 = <FormControl>this.form.get('control1');
const control2 = <FormControl>this.form.get('control2');

control1.valueChanges.subscribe(value => {
  if (value === 'first-condition') {
    control2.setValidators([Validators.required, ...])
  }
  else {
    control2.setValidators(null);
  }

  control2.updateValueAndValidity();
});

这是一个人为的示例,但该模式可以根据您的用例进行调整。不要忘记将订阅分配给您的视图模型,并在您的控件被销毁时取消订阅。

这是一个 StackBlitz 示例:https://stackblitz.com/edit/conditional-validation


0
投票

我有类似但略有不同的需求。

由于这是谷歌搜索时最受欢迎的帖子,这是我的解决方案,它可以适应我认为的大多数需求。

如果

formControlB
不为空,我需要
formControlA
为必需。

这是我的自定义验证器:

/**
 * Generates a validator function that checks if a reference control is not null.
 *
 * @param {string} referenceControlName - The name of the control in the same form group that holds the reference value.
 * @return {ValidatorFn} A validator function
 */
export function RequiredIfControlIsNotNullValidator(referenceControlName: string): ValidatorFn {
  return (currentControl: AbstractControl): { [key: string]: any } => {
    // Get the reference control from the parent formGroup
    const referenceControl = currentControl.parent ? currentControl.parent.get(referenceControlName) : null;
    
    // Throw an error if the reference control is null or undefined
    if (referenceControl == null)
      throw Error("Reference formControl is null or undefined");
    
    // Check if the reference control value is null or undefined
    const refValueIsNullOrUndefined = referenceControl.value == null || referenceControl.value == undefined;
    
    // Return the validation result
    return refValueIsNullOrUndefined ?  null : { [`${referenceControlName}IsNotNull`]: true };
  };
}

在您的组件中,以这种方式将其分配给您的 formControl :

this.myForm = new FormGroup({
  formControlA: new FormControl<string | null>({ value: null, disabled: false }, [Validators.nullValidator]),
  formControlB: new FormControl<string | null>({ value: null, disabled: false }, [RequiredIfControlIsNotNullValidator('formControlA')])
});

但是,每次

formControlB
的值更新时,我们都需要运行
formControlA
的验证。因此,在组件的 ngOnInit 中,对
formControlA

的 valueChanges 做出反应
public ngOnInit(): void {
// [...]
  this.myForm.get("formControlA").valueChanges.subscribe(vc => {
    this.visitForm.get('formControlB').updateValueAndValidity();
  });
// [...]
}

然后,验证器会生成一个自定义错误密钥,因此您可以使用它在模板中显示适当的错误消息

<form [formGroup]="myForm">
  <div>
    <input formControlName="formControlA" />
  </div>
  <div>
    <input formControlName="formControlB" />
    <span class="error" *ngIf="myForm.get('formControlB').hasError('formControlAIsNotNull')">
      The value of A is not null, hence B is required
    </span>
  </div>
</form>
© www.soinside.com 2019 - 2024. All rights reserved.