基于条件的动态验证 [英] Dynamic validation based on conditions
问题描述
场景:我有 4 个表单域.
- 说明(可选)
- 选择类型(必填)
- 电话(仅当选择类型"设置为电话"时才需要)
- 电子邮件(仅当选择类型"设置为电子邮件"时才需要)
当我更改选择类型字段时,根据选择,电话字段或电子邮件字段将可见.我需要验证这些字段.
问题:
当表单加载时,它只有描述,选择类型下拉菜单和保存按钮.
步骤 1:点击保存按钮而不输入任何输入,应该抛出一个警告说 Select Type is required
并且选择类型将是红色的.
第 2 步:选择一种类型,下一个输入变为可见并带有红色边框.这不应该发生,因为用户没有触及该字段.我该如何解决这个问题?
代码:
html
<form [formGroup]="groupForm" (ngSubmit)="onSubmit()"><部分><section class="input-row"><mat-form-field><input matInput type="test" placeholder="Description" id="description" formControlName="description"/></mat-form-field></节><section class="input-row"><mat-form-field><mat-select id="sourceType" formControlName="sourceType" placeholder="选择类型*"><mat-option value="电话">电话</mat-option><mat-option value="email">电子邮件</mat-option></mat-select></mat-form-field></节><section *ngIf="typeIsPhone" class="input-row"><mat-form-field><input matInput type="number" placeholder="Phone" id="phoneValue" formControlName="phoneValue"/></mat-form-field></节><section *ngIf="typeIsEmail" class="input-row"><mat-form-field><input matInput type="email" placeholder="Email" id="emailValue" formControlName="emailValue"/></mat-form-field></节></节><button mat-raised-button color="primary" type="submit" class="save">节省按钮></表单>
组件:
导出类 FormFieldOverviewExample 实现 OnInit {typeIsPhone = false;typeIsEmail = false;public groupForm: FormGroup = new FormGroup({描述:new FormControl(""),sourceType: new FormControl("", [Validators.required]),phoneValue: new FormControl("", [Validators.required]),emailValue: new FormControl("", [Validators.required])});构造函数(){}ngOnInit(): 无效 {this.groupForm.get("源类型").valueChanges.subscribe(this.setSourceType.bind(this));}setSourceType(SourceType: string) {this.typeIsPhone = SourceType === "电话";this.typeIsEmail = SourceType === "email";}提交(){const sourceTypeFormControl = this.groupForm.get("sourceType");const phoneEnteredFormControl = this.groupForm.get("phoneValue");const emailEnteredFormControl = this.groupForm.get("emailValue");如果(sourceTypeFormControl.errors.required){alert("需要源类型!");返回;} 别的 {如果(phoneEnteredFormControl.errors.required){alert("需要电话!");返回;}如果(emailEnteredFormControl.errors.required){alert("需要邮箱!");返回;}}}}
好像 FormControl 被禁用没有错误我建议使用禁用和启用的另一种方法,您可以在 这个stackblitz
ngOnInit(): void {const control=this.groupForm.get("sourceType")如果(控制)control.valueChanges.pipe(//首先使用startWith执行开始(控制.值)).subscribe(res=>this.setSourceType(res));//<--看看如何传递值}setSourceType(SourceType: string) {this.typeIsPhone = SourceType === "电话";this.typeIsEmail = SourceType === "email";const phoneControl=this.groupForm.get('phoneValue')const emailControl=this.groupForm.get('emailValue')如果(电话控制)phoneControl[SourceType==='phone'?'enable':'disable']()//(*)如果(电子邮件控制)emailControl[SourceType==='email'?'enable':'disable']()}//(*) 是一种缩写方式//如果 (SourceType=='phone')//phoneControl.enable()// 别的//phoneControl.disable()
注意:
//不能使用if (phoneEnteredFormControl.errors.required)//错误//用if (phoneEnteredFormControl.errors && phoneEnteredFormControl.errors.required)//OK
Scenario: I have 4 form fields.
- Description (Optional)
- Select Type (Required)
- Phone (Required only if Select Type is set to 'Phone')
- Email (Required only if Select Type is set to 'Email')
When I change anything is Select Type field, based on the selection, Phone field or Email field will be visible. I need to validate these fields.
Problem:
When the form loads, it'll have only description, select type dropdown and save button.
Step 1: Click save button without entering any input, should throw an alert saying Select Type is required
and select type will be red.
Step 2: Select a type, the next input becomes visible with red border. This should not happen since the user didn't touched the field. How can I solve this?
Code:
html
<div class="example-container">
<form [formGroup]="groupForm" (ngSubmit)="onSubmit()">
<section>
<section class="input-row">
<mat-form-field>
<input matInput type="test" placeholder="Description" id="description" formControlName="description"/>
</mat-form-field>
</section>
<section class="input-row">
<mat-form-field>
<mat-select id="sourceType" formControlName="sourceType" placeholder="Select Type*">
<mat-option value="phone">Phone</mat-option>
<mat-option value="email">Email</mat-option>
</mat-select>
</mat-form-field>
</section>
<section *ngIf="typeIsPhone" class="input-row">
<mat-form-field>
<input matInput type="number" placeholder="Phone" id="phoneValue" formControlName="phoneValue"/>
</mat-form-field>
</section>
<section *ngIf="typeIsEmail" class="input-row">
<mat-form-field>
<input matInput type="email" placeholder="Email" id="emailValue" formControlName="emailValue"/>
</mat-form-field>
</section>
</section>
<button mat-raised-button color="primary" type="submit" class="save">
Save
</button>
</form>
</div>
component:
export class FormFieldOverviewExample implements OnInit {
typeIsPhone = false;
typeIsEmail = false;
public groupForm: FormGroup = new FormGroup({
description: new FormControl(""),
sourceType: new FormControl("", [Validators.required]),
phoneValue: new FormControl("", [Validators.required]),
emailValue: new FormControl("", [Validators.required])
});
constructor() {}
ngOnInit(): void {
this.groupForm
.get("sourceType")
.valueChanges.subscribe(this.setSourceType.bind(this));
}
setSourceType(SourceType: string) {
this.typeIsPhone = SourceType === "phone";
this.typeIsEmail = SourceType === "email";
}
onSubmit() {
const sourceTypeFormControl = this.groupForm.get("sourceType");
const phoneEnteredFormControl = this.groupForm.get("phoneValue");
const emailEnteredFormControl = this.groupForm.get("emailValue");
if (sourceTypeFormControl.errors.required) {
alert("Source Type is required!");
return;
} else {
if (phoneEnteredFormControl.errors.required) {
alert("Phone is required!");
return;
}
if (emailEnteredFormControl.errors.required) {
alert("email is required!");
return;
}
}
}
}
As if a FormControl is disabled don't has errors I suggest another aproach using disable and enable that you can see in this stackblitz
ngOnInit(): void {
const control=this.groupForm.get("sourceType")
if (control)
control.valueChanges.pipe( //Use startWith to execute at first
startWith(control.value)
).subscribe(res=>this.setSourceType(res)); //<--see how pass the value
}
setSourceType(SourceType: string) {
this.typeIsPhone = SourceType === "phone";
this.typeIsEmail = SourceType === "email";
const phoneControl=this.groupForm.get('phoneValue')
const emailControl=this.groupForm.get('emailValue')
if (phoneControl)
phoneControl[SourceType==='phone'?'enable':'disable']() //(*)
if (emailControl)
emailControl[SourceType==='email'?'enable':'disable']()
}
//(*) is a abreviated way to say
// if (SourceType=='phone')
// phoneControl.enable()
// else
// phoneControl.disable()
NOTE:
//You can not use
if (phoneEnteredFormControl.errors.required) //WRONG
//use
if (phoneEnteredFormControl.errors && phoneEnteredFormControl.errors.required) //OK
这篇关于基于条件的动态验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!