基于条件的动态验证 [英] Dynamic validation based on conditions

查看:24
本文介绍了基于条件的动态验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景:我有 4 个表单域.

  1. 说明(可选)
  2. 选择类型(必填)
  3. 电话(仅当选择类型"设置为电话"时才需要)
  4. 电子邮件(仅当选择类型"设置为电子邮件"时才需要)

当我更改选择类型字段时,根据选择,电话字段或电子邮件字段将可见.我需要验证这些字段.

问题:

当表单加载时,它只有描述,选择类型下拉菜单和保存按钮.

步骤 1:点击保存按钮而不输入任何输入,应该抛出一个警告说 Select Type is required 并且选择类型将是红色的.

第 2 步:选择一种类型,下一个输入变为可见并带有红色边框.这不应该发生,因为用户没有触及该字段.我该如何解决这个问题?

代码:

Stackblitz 代码

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.

  1. Description (Optional)
  2. Select Type (Required)
  3. Phone (Required only if Select Type is set to 'Phone')
  4. 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:

Stackblitz 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆