web-dev-qa-db-fra.com

Angular Matériau: réinitialisation de la forme réactive affiche une erreur de validation

J'utilise angular5 reactivemodule pour afficher un formulaire dans ma demande. J'avais également utilisé le validateur requis qui rendra ensuite le champ de couleur rouge et affichera un message d'erreur à l'utilisateur.

Il fonctionne comme prévu, mais lorsque je réinitialise le formulaire à l'aide

this.form.reset ()

le formulaire me montre une erreur de validation que le champ spécifique est obligatoire. J'ai également utilisé form.markAsPristine () ou form.markAsUntouched () pour le faire fonctionner, mais le problème persiste après l'application de plusieurs combinaisons de paires possibles.

exemple.html

<form [formGroup]="checkForm" (ngSubmit)="submitForm()">
  <mat-form-field>
    <input matInput formControlName="name" placeholder="name" />
    <mat-error *ngIf="checkForm.get('name').errors?.required">
      Name is required.
    </mat-error>
  </mat-form-field>
  <mat-form-field>
    <input matInput formControlName="email" placeholder="email" />
    <mat-error *ngIf="checkForm.get('email').errors?.required">
      Name is required.
    </mat-error>
  </mat-form-field>
  <button [disabled]="checkForm.invalid" type="submit">add</button>
</form>

example.ts

checkForm  = this.formBuilder.group({
  'name': ['', Validators.required],
  'email': ['', Validators.required]
});

submitForm() {
   this.checkForm.reset();
   // this.checkForm.markAsPristine();
   this.checkForm.markAsUntouched();      
}

Toute aide est appréciée.

7
Ajay

Par défaut , Angular/Material surveiller l'état d'erreur de formControl non seulement par touched mais aussi soumis le statut du formulaire, voir ci-dessous code source .

isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
  return !!(control && control.invalid && (control.touched || (form && form.submitted)));
                                                                       ^^^^^^^^^^^^^^
}

Pour la raison ci-dessus, vous devez également réinitialiser le formulaire à l'état unsubmitted.


Vous pouvez appeler resetForm of FormGroupDirective ( obtenir l'instance par ViewChild) car cela réinitialisera les données du formulaire et soumettra l'état.

<form #form="ngForm" [formGroup]="checkForm" (ngSubmit)="submitForm(form)">
  ...
</form>

@ViewChild('form') form;

submitForm() {
  this.form.resetForm();
  ...
}

Vous pouvez également remplacer celui par défaut en implémentant ErrorStateMatcher avec des conditions personnalisées telles que ignorer le statut soumis du formulaire et l'appliquer sur les composants de matériau.

<mat-form-field>
  <input matInput formControlName="name" placeholder="name" [errorStateMatcher]="errorMatcher" />
  <mat-error *ngIf="checkForm.get('name').errors?.required">
    Name is required.
  </mat-error>
</mat-form-field>

// define custom ErrorStateMatcher
export class CustomErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl, form: NgForm | FormGroupDirective | null) {
    return control && control.invalid && control.touched;
  }
}

// component code
@Component({...})
export class CustomComponent {
  // create instance of custom ErrorStateMatcher
  errorMatcher = new CustomErrorStateMatcher();
}

voir fixe démo.

15
Pengyy

Tout ce que vous devez faire est d'éviter la méthode (ngSubmit) Sur votre formulaire réactif:
1. Supprimer (ngSubmit)="submitForm()" De votre balise de formulaire
1. Modifiez le type de bouton de votre formulaire de 'submit' À 'button'
2. Sur ce bouton, vous souhaitez définir une action de clic sur (click)="submitForm()"
3. dans la méthode submitForm() faites:

this.checkForm.markAsPristine();
this.checkForm.markAsUntouched();

Cela soumettra le formulaire et réinitialisera sa valeur sans alerter les validateurs

13
Alex Oleksiiuk