跨域验证的最佳方式

跨域验证的最佳方式

本文介绍了实现 Angular 跨域验证的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出在 Angular 中实现跨领域验证的最佳方法.

I am trying to figure out the best way to implement cross field validation in Angular.

例如,我有一个选择字段,它使另一个字段成为必填字段.

For example, I have a select field that makes another field mandatory.

我希望能够:

  • 如果字段无效,请更改字段的边框颜色
  • 当字段变为必填项时,在字段前显示 *
  • 显示一条特定的错误消息,说明违反了哪些验证规则.

到目前为止,我想出了三个解决方案,但它们对我来说并不那么令人信服.

So far, I came up with three solutions but they don't feel so convincing to me.

  • 聆听选择字段的更改并更新第二个字段的验证器.
  • 监听两个字段的变化并手动执行 setErrors
  • 将验证提升到 formGroup(这可能会让人感觉非常麻烦,因为验证状态现在存储在 formGroup 中,而不是直接在 formControl 中可用).

这是一个 Stackblitz 实现,用于演示我的调查.

Here is a Stackblitz implementation that demos my investigations.

推荐答案

更新 - 更好的方法

在表单上创建 customValidator 并使用验证器将 setError 用于所需的控件.使用 setError,让 Angular 为我们添加 ng-invalid,广告我们不需要订阅值更改.见:

Create the customValidator over the form and use the validator to use setError to the control required. Using setError, make that Angular adds ng-invalid for us, ad we needn't subscribe to value change. See:

form: FormGroup = new FormGroup(
  {
    input1: new FormControl('optional'),
    input2: new FormControl(null),
  },
  { validators: this.customValidatorForm() },
);

customValidatorForm() {
  return (form: FormGroup) => {
    const error =
      form.get('input1').value != 'optional' && !form.get('input2').value
        ? { required: true }
        : null;
    form.get('input2').setErrors(error); //<--see the setErrors
    return error;
  };
}

参见 stackblitz

旧答案

只需使用 customValidator 像:

form: FormGroup = new FormGroup({
  input1: new FormControl('optional'),
  input2: new FormControl(null, this.customValidator()),
});

customValidator() {
  return (control: any) => {
    if (!control.parent) return null;

    let mandatory = control.parent.get('input1').value;
    return mandatory != 'optional' && !control.value ? { required: true } : null;
  };
}

不要求 control.parent 的另一个选项是使用 .bind(this).这允许我们在验证器内部访问我们组件的所有变量,当然还可以访问 this.form:

Another option for not ask for control.parent it's use .bind(this). This allow us have inside the validator to all the variables of our component, and of course access to this.form:

form: FormGroup = new FormGroup({
  input1: new FormControl('optional'),
  input2: new FormControl(null, this.customValidator().bind(this)), //<--bind(this)
});

customValidatorBind() {
  return (control: any) => {
    if (!this.form) return null;

    let mandatory = this.form.get('input1').value;
    return mandatory != 'optional' && !control.value ? { required: true } : null;
  };
}

好吧,因为我们希望当更改 input1 input2 被选中时,您需要使用,在创建表单后订阅 valueChanges:

Well, as we want that when change input1 input2 was checked, you need use, after create the form subscribe to valueChanges:

this.form.get('input1').valueChanges.subscribe(() => {
  this.form.get('input2').updateValueAndValidity();
});

这篇关于实现 Angular 跨域验证的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:25