角度反应形式 - 验证变化和模糊两者

Posted

技术标签:

【中文标题】角度反应形式 - 验证变化和模糊两者【英文标题】:Angular reactive forms - validate on change and blur both 【发布时间】:2019-01-15 16:15:53 【问题描述】:

我在我的应用程序中使用角度反应形式。我要求某些验证需要在更改时运行(角度表单验证的默认行为),而其他一些验证只需要在 blur 上运行以提高性能。

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

问题是:我们能否配置有角度的反应形式,以便在更改时运行一些验证,而在模糊时运行另一些验证。或者我们还有其他选择吗?

【问题讨论】:

【参考方案1】:

是的,你可以,因为 Angular 5 你可以这样做:

例子:

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

【讨论】:

这样做,valueChanges 仅在模糊时发出值,这并不能回答他的问题。【参考方案2】:

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

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

一个检查电子邮件的格式实际上是一封电子邮件,在客户端有一个同步验证器和内置验证器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();

【讨论】:

以上是关于角度反应形式 - 验证变化和模糊两者的主要内容,如果未能解决你的问题,请参考以下文章

markdown 使用Bootstrap样式验证角度反应形式

显示角度反应形式错误消息的最佳方法,一个表单控制多个验证错误?

如何在角度 2 中以反应形式重置验证器?

在角度反应形式验证器中使用 google-libphonenumber

[密码并以角度8的反应形式确认密码验证

我想编写可以以任何角度形式使用的通用验证 - 正常反应已经完成并且工作正常