0

场景:我有 4 个表单域。

  1. 说明(可选)
  2. 选择类型(必填)
  3. Phone (Required only if Select Type is set to 'Phone')
  4. Email (Required only if Select Type is set to 'Email')

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

问题:

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

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

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

代码:

Stackblitz 代码

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> 

零件:

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;
      }
    }
  }
}
4

2 回答 2

1

好像禁用 FormControl 没有错误我建议使用另一种方法禁用和启用,您可以在此 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()

笔记:

  //You can not use 
  if (phoneEnteredFormControl.errors.required) //WRONG
  //use 
  if (phoneEnteredFormControl.errors && phoneEnteredFormControl.errors.required) //OK
于 2020-03-03T07:59:45.963 回答
0

问题源于提交的属性、隐含 type=submit 的按钮以及默认 ErrorStateMatcher 处理这种情况的方式。

也许使用

type="button" (click)="onSubmit()"
于 2020-03-03T06:47:13.287 回答