[英]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});
});
我多次面对同样的“问题”。 这是出于某种目的。 它将对“经典”验证器(非定制)执行相同的操作。
我一直在做的事情与此类似:
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.