繁体   English   中英

如果为空,则对反应形式的角度验证应打开或关闭,但如果输入为空,则不进行切换

[英]Angular validation on reactive form should toggle on or off if empty, but does not toggle if input is emptied

我已经使用Angular Reactive Forms建立了一个简单的表单。 我有一个自定义的验证程序功能,该功能检查电话号码输入的格式。 如果用户选择不输入电话号码,但如果输入一个电话号码,然后确认其输入,我想允许输入空的内容。

为此,我订阅了表单控件上的值更改,并使用setValidators方法切换验证字段是否为空:

phoneControl.valueChanges.subscribe(() => {
  if (phoneControl.value === "") {
    phoneControl.setValidators(null);
  } else {
    phoneControl.setValidators(this.phoneValidator());
  }
});

在StackBlitz上查看完整的代码

该代码最初有效, form.valid为true。 当我输入一个数字时,它将打开验证,然后根据我的RegEx成功验证它并显示错误。

但是,当我清空该字段时,即使我的代码应将验证器设置为null ,错误也不会消失并且表单form仍然无效。 您可以在上面的StackBlitz示例中看到这一点。

我不知道为什么会这样。 有任何想法吗?

我会建议您这样做-

if (phoneControl.value === "") {
        phoneControl.clearValidators();
} else {
        phoneControl.setValidators(this.phoneValidator());
}
phoneControl.updateValueAndValidity({emitEvent: false});

清除验证器是一种比将其设置为null更好的方法。

要验证电话号码输入,可以使用@ rxweb / reactive-form-validators的 模式验证

您只需要在formControl中提及电话号码正则表达式,如下所示:

ngOnInit() {
        this.userFormGroup = this.formBuilder.group({
            phoneNumber:['', RxwebValidators.pattern({expression:{'onlyPhoneNumber': /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/} })], 
        });
    }

对于错误消息,您可以将消息绑定到app.component.ts中,如下所示:

ngOnInit(){
    ReactiveFormConfig.set({"validationMessage":{"onlyPhoneNumber":"Invalid phone number"}});
  }

这是完整的HTML代码:

<div>
  <form  [formGroup]="userFormGroup">
    <div class="form-group">
      <label>Phone Number</label>
      <input type="text" formControlName="phoneNumber" class="form-control"  />
     <small class="form-text text-danger" *ngIf="userFormGroup.controls.phoneNumber.errors">{{userFormGroup.controls.phoneNumber.errors.onlyPhoneNumber.message}}<br/></small>  
    </div>
    <button [disabled]="!userFormGroup.valid" class="btn btn-primary">Submit</button>
  </form>
</div>

这是完整的组件代码

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from "@angular/forms"
import { RxwebValidators } from '@rxweb/reactive-form-validators';

@Component({
    selector: 'app-pattern-add-validator',
    templateUrl: './pattern-add.component.html'
})
export class PatternAddValidatorComponent implements OnInit {
    userFormGroup: FormGroup

    constructor(
        private formBuilder: FormBuilder )
    { }

    ngOnInit() {
        this.userFormGroup = this.formBuilder.group({
            phoneNumber:['', RxwebValidators.pattern({expression:{'onlyPhoneNumber': /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/} })], 
        });
    }
}

工作堆闪电战

动态设置验证器时,我们需要调用updateValueAndValidity() 还要记住添加emitEvent: false ,这意味着不会触发valueChanges (以防止循环)。 因此,将您的代码更改为:

phoneControl.valueChanges.subscribe(() => {
  if (phoneControl.value === "") {
    phoneControl.setValidators(null);
    // or
    // phoneControl.setValidators([]);
    // or as mentioned by Tilak
    // phoneControl.clearValidators();
  } else {
    phoneControl.setValidators(this.phoneValidator());
  }
  phoneControl.updateValueAndValidity({emitEvent: false});
});

您的StackBlitz

我多次面对同样的“问题”。 这是出于某种目的。 它将对“经典”验证器(非定制)执行相同的操作。

我一直在做的事情与此类似:

phoneControl.valueChanges.subscribe(() => {
  if (phoneControl.value === "") {
    phoneControl.reset();
    phoneControl.markAsPristine();
    phoneControl.markAsUntouched();
    phoneControl.updateValueAndValidity();
  } else {
    phoneControl.setValidators(this.phoneValidator());
  }
});

如果仅使用updateValueAndValidity() ,则即使该值为空,您的表单也会说它处于有效状态。

通过编辑验证器本身就可以了:

  isValidPhoneNumber(phoneNumber: string) {
    if(phoneNumber === "")return true;
    return new RegExp(/^[ 0 ]{1,1}?[0-9- ]{9,15}$/).test(phoneNumber);
  }

并删除订阅。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM