角度反应形式-验证更改并模糊两者

时间:2019-01-15 16:15:53

标签: angular validation

我在我的应用程序中使用了角反应形式。我要求某些验证需要在更改时运行(角度形式验证的默认行为),而其他一些验证仅需要在模糊时运行才能提高性能。

基本上,当用户开始在文本框中键入内容时,我要执行客户端验证,并以用户类型显示错误。另外,我需要在文本框中进行服务器端业务验证,我想在模糊时执行此操作。

问题是:我们可以配置角度反应形式,以便在更改时进行某些验证,而在模糊时进行其他验证。还是我们还有其他选择?

2 个答案:

答案 0 :(得分:0)

是的,由于Angular 5,您可以这样做:

示例:

this.email = new FormControl(null, {
   validators: Validators.required,
   updateOn: 'blur'
});

答案 1 :(得分:0)

我遇到了同样的问题,因为我找不到在同一个输入字段上设置不同的更新策略,我找到了一个很好的解决方法,我在下面的例子中解释:

在注册表单中,我有一封电子邮件的输入字段,我需要两个具有两种不同策略的验证器:

  • 检查电子邮件的格式实际上是电子邮件格式,客户端有一个同步验证器,内置验证器 Validators.email,我希望这个与 updateOn: "change" 一起使用它在用户输入时被检查

  • 如果电子邮件不存在并带有异步 API CALL,则另一个检查数据库,我希望使用 updateOn: "blur"(当用户离开输入时)完成此操作,并且仅当电子邮件格式良好(因此当第一个验证器有效时)。

在声明第一个验证器的 ts 文件中创建表单组,无需设置 updateOn: "change",因为它是默认值:

  public myForm: FormGroup;
  private emailSubscription: Subscription;

  this.myForm = this.fb.group({
    // ... some other inputs
    email : ["", {validators: Validators.email}]  
  })

在 emailControl.touched 上的过滤器等于 updateOn: "blur" 之后,我在 AfterViewInit 中表单更改的订阅中创建了异步验证器,然后,这里不相关,它检查电子邮件不存在API调用

ngAfterViewInit() {
  // Gets input control
  const emailControl = this.signupForm.get("email");

  // Subscribes to the input control's valueChanges Observable
  this.emailSubcription = emailControl.valueChanges
    .pipe(
      // Checks only when email input is left and valid (so when
      // the "genuine" Vaildators.email is verified
      filter((checkedEmail) => emailControl.touched && emailControl.valid),

      // API CALL checking if email exists, we use switchMap to end previous
      // call if user keep typing and result has not been returned yet
      switchMap((inputEmail) => {
        // variable made to send data to server with API CALL, 
        // not relevant here
        const checkedEmail = { checkedEmail: inputEmail.toLowerCase() };
        // API call to check email exists, not relevant here, 
        // could be any async method 
        return this.http.post("/api/user/emailExists", checkedEmail);
      })
    )
    .subscribe((emailExists: boolean) => {
      // Sets an error on the input control if the email exists,
      // so the error can be then processed as needed (for example
      // to show a div in template or use with mat-error of the input)
      if (emailExists === true) {
        emailControl.setErrors(
          { emailNotAvailable: true },
          { emitEvent: false }
        );
      }
    });
  }

最后,不要忘记取消订阅 observable:

public ngOnDestroy() {
  if (this.emailSubscription) this.emailSub.unsubscribe();
}