首页 > 解决方案 > Angular 跨字段验证和自定义验证一起使用

问题描述

我有 7 天的开放和封闭领域。open 和 close 参数可以有 hh:mm 或单词“Closed”。因此,每个打开和关闭字段都有正则表达式验证以匹配 hh:mm 或“关闭”字。此外,我正在尝试添加额外的跨字段验证,以确保一天中的一个字段不会被关闭。如果两者都关闭,则可以,但不是其中之一。

在此处输入图像描述

如果我有任何一个验证,代码似乎工作,但如果我有他们两个,它不工作。我尝试将示例代码放在 stackblitz 中。

https://stackblitz.com/angular/qvjapnglrrp

正则表达式验证

validateInput(c: FormControl) {
    const hourMinpattern = /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$/;
    const closedPattern = /^Closed$/;
    return hourMinpattern.test(c.value) || closedPattern.test(c.value)
      ? null
      : {
          validateInput: {
            valid: false
          }
        };
  }

跨领域验证

mondayOpenCloseValidator(formGroup: FormGroup): ValidationErrors | null {
    const open = formGroup.get("mondayOpen");
    const close = formGroup.get("mondayClose");

    if (
      (open.value === "Closed" || close.value === "Closed") &&
      open.value !== close.value
    ) {
      close.setErrors({ badState: true });
      close.markAllAsTouched();
      return { badState: true };
    }

    close.setErrors(null);                
    return null;
  }

表单生成器

this.editForm = this.formBuilder.group(
  {
    mondayOpen: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ]),
    mondayClose: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ]),
    tuesdayOpen: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ]),
    tuesdayClose: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ])
  },
  {
    validator: [
      this.mondayOpenCloseValidator,
      this.tuesdayOpenCloseValidator
    ]
  }
);

标签: angularangular-materialangular-reactive-forms

解决方案


我认为您的问题出在自定义验证器上-在验证结束时,您会删除所有错误,包括其他验证器的错误-

删除这一行:

close.setErrors(null);

因此生成的代码将如下所示:

ondayOpenCloseValidator(formGroup: FormGroup): ValidationErrors | null {
    const open = formGroup.get("mondayOpen");
    const close = formGroup.get("mondayClose");

    if (
      (open.value === "Closed" || close.value === "Closed") &&
      open.value !== close.value
    ) {
      close.setErrors({ badState: true });
      close.markAllAsTouched();
      return { badState: true };
    }
            
    return null;
  }

推荐阅读