首页 > 解决方案 > 如何在 Angular 中重置反应性 Angular Material 表单?

问题描述

我正在尝试重置由 Angular Material 创建的反应形式(复选框除外)。我试过用this.formdata.reset(). 它正在重置表单,但它正在制作它touched。所以我使用this.formdata.markAsUntouched()了,但它没有任何不同。下面是我的代码:

app.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, Validators, FormArray, FormControl, NgForm } from '@angular/forms';

export class FormComponent implements OnInit{

  public states = [];

  Gender: model[] = [{value: 'M', option: 'Male'}, {value: 'F', option: 'Female'}];
  Vehicles: model[] = [{value: '2 wheelers', option: '2 wheelers'}, {value: '4 wheelers', option: '4 wheelers'}];

  constructor(private _statesService: StatesService, private fb: FormBuilder) {}

  // Initialize each field of form with FormBuilder
  formdata = this.fb.group({
    name: ['', [Validators.required, Validators.minLength(3)]], phone: ['', [Validators.required, Validators.minLength(12)]],
    gender: ['', Validators.required], vehicles: new FormArray([],Validators.required)
  });

  // Retreiving values of form field
  get Name()
  {return this.formdata.get('name');}

  get Phone()
  {return this.formdata.get('phone');}

  get Vehiclesmethod()
  {return this.formdata.get('vehicles');}

  get Genderval()
  {return this.formdata.get('gender');}

  onCheckChange(event) {
    const formArray: FormArray = this.formdata.get('vehicles') as FormArray;

    /* Selected */
    if(event.target.checked){
      // Add a new control in the arrayForm
      formArray.push(new FormControl(event.target.value));
    }
    /* unselected */
    else{
      // find the unselected element
      let i: number = 0;

      formArray.controls.forEach((ctrl: FormControl) => {
        if(ctrl.value == event.target.value) {
          // Remove the unselected element from the arrayForm
          formArray.removeAt(i);
          return;
        }
        i++;
      });
    }
  }
  @ViewChild('f') private f: NgForm;
  // Submit method
  onSubmit()
  {
    if(this.formdata.invalid){return ;}
    console.log(this.formdata.value);
    alert('submitted');
    // Reset form
    this.formdata.reset();
    this.formdata.markAsUntouched();
  }
}

app.component.html

<form [formGroup]="formdata" (ngSubmit)="onSubmit()" #f="ngForm"> 
            <div class="form-row">
                <div class="col">
                    <p>
                        <mat-form-field appearance="outline" class="field_size">
                            <mat-label>Name</mat-label>
                            <input type="text" matInput formControlName="name">
                            <mat-error *ngIf="Name.errors?.required">Name required</mat-error>
                            <mat-error *ngIf="Name.errors?.minlength">Minimum 3 characters required</mat-error>
                        </mat-form-field>
                    </p>
                </div>
                <div class="col">
                    <p>
                        <mat-form-field appearance="outline" class="field_size">
                            <mat-label>Phone Number</mat-label>
                            <input type="tel" matInput appPhoneMask formControlName="phone" maxlength="12">
                            <mat-error *ngIf="Phone.errors?.required">Phone number required</mat-error>
                            <mat-error *ngIf="Phone.errors?.minlength">Number is less than 10 digits</mat-error>
                        </mat-form-field>
                    </p>
                </div>
            </div>

            <div class="form-row">
                <div class="col">
                    <label>Gender</label><br>
                    <mat-radio-group formControlName="gender">
                        <mat-radio-button *ngFor="let g of Gender; let i = index" [value]="g.value">{{ g.option }}</mat-radio-button>
                    </mat-radio-group><br>
                    <small *ngIf="Genderval.errors?.required" style="color: red;">Please select Gender</small>
                </div>
                <div class="col">
                    <label>Vehicles</label><br>
                    <div class="form-inline">
                        <span class="custome-control custom-checkbox mr-sm-2" *ngFor="let v of Vehicles,let i=index">
                            <input type="checkbox" class="custom-control-input" id="{{i}}" [value]="v.value" (change)="onCheckChange($event)">
                            <label for="{{i}}" class="custom-control-label">{{v.option}}</label>
                        </span>
                    </div>
                </div>
            </div>
            <div class="form-row">
                <button mat-flat-button color="primary" type="submit" class="button" [disabled]="!formdata.valid">Submit</button>
            </div>
        </form>

注意:FormBuilder部分和视图部分中的每个字段的值都将被清空。但是它显示的视图部分中的复选框仍然被选中。

请帮帮我我已经尝试了很多方法,但没有任何工作正常。

标签: angulartypescriptangular-materialangular9

解决方案


我不确定是否适用于整个表单,但对于每个 FormControl 都可以。您需要在选项中指定更改后不发出事件。

this.formdata.reset('', {emitEvent: false});

在此之后,如果您的表单仍被标记为已触摸,请尝试您的解决方案 + 检查表单更改:

constructor(private cd: ChangeDetectorRef) {}

this.formdata.markAsUntouched();
this.cd.detectChanges();

推荐阅读