Как лучше всего подойти к сбросу реактивной угловой формы?

У меня есть реактивная форма с использованием Angular Material input (mdInput), который инициализируется следующим образом с помощью FormBuilder:

contactForm: FormGroup;

this.contactForm = this.fb.group({
  name: ['', [Validators.required, Validators.maxLength(128)]],
  email: ['', [Validators.required, Validators.email]],
  subject: ['', [Validators.required, Validators.maxLength(128)]],
  message: ['', [Validators.required, Validators.maxLength(1000)]]
});

onSubmit(): void {
  this.resetForm();
}

private resetForm(): void {
  this.contactForm.reset();
}    

С входами Angular Material, связанными с соответствующими элементами FormControl с подключением к (ngSubmit):

<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <md-input-container>
    <input mdInput formControlName="name" placeholder="Name">
  </md-input-container>

  <button type="submit" md-raised-button [disabled]="contactForm.invalid">Submit</button>

When calling reset() on the FormGroup contactForm (this.contactForm.reset(), the form elements values are successfully cleared/replaced with empty strings, but the elements are both immediately dirty and touched with CSS classesng-invalid&&ng-touchedpresent on the elements. Strangely they also have theng-pristineCSS class on them after thereset()`.

Каков наиболее эффективный способ подойти к сбросу формы, включая очистку / сброс значений FormControl и их пометку как неприкосновенные и не грязные? Использует markAsUntouched() или markAsPristine()? Используется ли setValue() или reset() с определенными параметрами? Цель состоит в том, чтобы сбросить форму, как если бы пользователь взаимодействовал с ней впервые.

Обновление. Вот Stackblitz, показывающий эту проблему в действии.

Спасибо за любую помощь, которую вы можете оказать.


person Alexander Staroselsky    schedule 02.09.2017    source источник
comment
Так быть не должно. Согласно исходному коду, reset пометит форму как нетронутую и нетронутую. См. github.com/angular/angular/blob / master / packages / forms / src /   -  person Harry Ninh    schedule 02.09.2017
comment
Я обновил ответ, чтобы включить Stackblitz, чтобы продемонстрировать проблему в действии. Вы заметите, что onSubmit вызывает reset (), в результате чего все входы, которые имеют Validators, будут затронуты и загрязнены. Спасибо!   -  person Alexander Staroselsky    schedule 02.09.2017
comment
Каким-то образом использование ngSubmit нарушает поток. Я вижу все входы нетронутыми + нетронутыми, но ошибки все еще отображаются. Если вы измените кнопку отправки на что-то вроде <button type="button" (click)="onSubmit()", она будет работать   -  person Harry Ninh    schedule 02.09.2017


Ответы (1)


Как упоминал @Harry Ninh в комментариях, использование обычной кнопки вместо ngSubmit исправит поведение. Это связано с тем, что по умолчанию ошибки материала отображаются, когда ввод - invalid и либо touched, либо submitted. Об этом есть длинная ветка здесь, но в основном это вызов reset() в элементе управления формы или группа форм не сбрасывает фактическую форму, а только значения.

Вы можете сделать одно из следующего:

  1. Используйте обходной путь, упомянутый @Harry Ninh
  2. Используйте ViewChild, чтобы получить доступ к FormGroupDirective и сбросить его.

Глянь сюда:

@ViewChild(FormGroupDirective) myForm;

contactForm: FormGroup;

constructor(private fb: FormBuilder) {
  this.createForm();
}

private createForm(): void {
  this.contactForm = this.fb.group({
    name: ['', [Validators.required, Validators.maxLength(128)]],
    email: ['', [Validators.required, Validators.email]],
    subject: ['', [Validators.required, Validators.maxLength(128)]],
    message: ['', [Validators.required, Validators.maxLength(1000)]]
  });
}

onSubmit(): void {
  this.resetForm();
}

private resetForm(): void {
  if (this.myForm) {
    this.myForm.resetForm();
  }
}
person Will Howell    schedule 05.09.2017