Como limpar o formulário após o envio no Angular 2?

87

Eu tenho algum componente angular 2 simples com modelo. Como limpar o formulário e todos os campos após o envio ?. Não consigo recarregar a página. Depois de definir os dados com o date.setValue('')campo ainda touched.

import {Component} from 'angular2/core';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, Control} from 'angular2/common';

@Component({
    selector: 'loading-form',
    templateUrl: 'app/loadings/loading-form.component.html',
    directives: [FORM_DIRECTIVES]
})

export class LoadingFormComponent {
    private form:ControlGroup;
    private date:Control;
    private capacity:Control;

    constructor(private _loadingsService:LoadingsService, fb:FormBuilder) {
        this.date = new Control('', Validators.required);
        this.capacity = new Control('', Validators.required);
        this.form = fb.group({
            'date': this.date,
            'capacity': this.capacity
        });
    }

    onSubmit(value:any):void {
        //send some data to backend
    }
}

loading-form.component.html

<div class="card card-block">
    <h3 class="card-title">Loading form</h3>

    <form (ngSubmit)="onSubmit(form.value)" [ngFormModel]="form">
        <fieldset class="form-group" [class.has-danger]="!date.valid && date.touched">
            <label class="form-control-label" for="dateInput">Date</label>
            <input type="text" class="form-control form-control-danger form-control-success" id="dateInput"
                   min="0" placeholder="Enter loading date"
                   [ngFormControl]="form.controls['date']">
        </fieldset>
        <fieldset class="form-group" [class.has-danger]="!capacity.valid && capacity.touched">
            <label class="form-control-label" for="capacityInput">Capacity</label>
            <input type="number" class="form-control form-control-danger form-control-success" id="capacityInput"
                   placeholder="Enter capacity"
                   [ngFormControl]="form.controls['capacity']">
        </fieldset>
        <button type="submit" class="btn btn-primary" [disabled]="!form.valid">Submit
        </button>
    </form>
</div>
masel.popowo
fonte

Respostas:

135

Consulte também https://angular.io/docs/ts/latest/guide/reactive-forms.html (seção "redefinir os sinalizadores de formulário")

> = RC.6

No RC.6, deve haver suporte para atualizar o modelo de formulário. Criar um novo grupo de formulários e atribuir amyForm

[formGroup]="myForm"

também terá suporte ( https://github.com/angular/angular/pull/11051#issuecomment-243483654 )

> = RC.5

form.reset();

No novo módulo de formulários (> = RC.5) NgFormtem um reset()método e também suporta um resetevento de formulários . https://github.com/angular/angular/blob/6fd5bc075d70879c487c0188f6cd5b148e72a4dd/modules/%40angular/forms/src/directives/ng_form.ts#L179

<= RC.3

Isso vai funcionar:

onSubmit(value:any):void {
  //send some data to backend
  for(var name in form.controls) {
    (<Control>form.controls[name]).updateValue('');
    /*(<FormControl>form.controls[name]).updateValue('');*/ this should work in RC4 if `Control` is not working, working same in my case
    form.controls[name].setErrors(null);
  }
}

Veja também

Günter Zöchbauer
fonte
2
@ masel.popowo Sim, se quiser pristine, ..., então reconstruir o formulário é atualmente a única opção.
Günter Zöchbauer
@ günter-zöchbauer como você reconstrói o formulário?
SimonHawesome,
2
Ainda não experimentei, mas acho que você apenas abandona o grupo de controle e cria um novo. Mova o código para uma função para que possa chamá-la repetidamente, se necessário.
Günter Zöchbauer
+1 para setErrors (). A propósito, um erro, eu documento aqui um erro que cometi no caso de outra pessoa fazer algo semelhante: no caso de você usar um marcador, por exemplo, 'foo', não chame control.updateValue ('foo'), mas sim control.setValue (null)
Mike Argyriou
Não sei sobre um setValue()método de controle. Apenas updateValue() github.com/angular/angular/blob/master/modules/angular2/src/…
Günter Zöchbauer
32

A partir do Angular2 RC5, myFormGroup.reset()parece funcionar.

ebhh2001
fonte
isso funciona no angular 4, usei para redefinir as validações de formulário
Grim
13

Para redefinir seu formulário após o envio, você pode simplesmente invocar this.form.reset(). Ao ligar reset():

  1. Marque o controle e os controles filhos como originais .
  2. Marque o controle e os controles filho como intocados .
  3. Defina o valor do controle e dos controles filhos como valor personalizado ou nulo .
  4. Atualize o valor / validade / erros das partes afetadas.

Encontre esta solicitação de pull para uma resposta detalhada. Para sua informação, este PR já foi mesclado com o 2.0.0.

Esperançosamente, isso pode ser útil e me avise se você tiver outras perguntas em relação ao Formulários Angular2.

JayKan
fonte
1
se eu usar o reset, então as validações não são aplicadas. como posso fazer com que ambos funcionem?
Nisha de
10

Faça uma chamada clearForm();em seu arquivo .ts

Tente como o exemplo de trecho de código abaixo para limpar os dados do formulário.

clearForm() {

this.addContactForm.reset({
      'first_name': '',
      'last_name': '',
      'mobile': '',
      'address': '',
      'city': '',
      'state': '',
      'country': '',
       'zip': ''
     });
}
mkumar0304
fonte
9
import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';
@Component({
    selector: 'example-app',
    template: '<form #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
        <input name="first" ngModel required #first="ngModel">
        <input name="last" ngModel>
        <button>Submit</button>
    </form>
    <p>First name value: {{ first.value }}</p>
    <p>First name valid: {{ first.valid }}</p>
    <p>Form value: {{ f.value | json }}</p>
    <p>Form valid: {{ f.valid }}</p>',
})
export class SimpleFormComp {
    onSubmit(f: NgForm) {

        // some stuff

        f.resetForm();
    }
}
Rahul Tiwari
fonte
@ Isso funciona bem quando temos que limpar todos os campos. Mas como podemos implementar o mesmo para limpar apenas alguns campos?
Akhilesh Pothuri
8

Aqui está como faço isso no Angular 7.3

// you can put this method in a module and reuse it as needed
resetForm(form: FormGroup) {

    form.reset();

    Object.keys(form.controls).forEach(key => {
      form.get(key).setErrors(null) ;
    });
}

Não havia necessidade de ligar form.clearValidators()

Mauricio Gracia Gutierrez
fonte
2
Essa é a melhor (e só funciona para mim) solução para limpar o formulário construído com FormBuilder que tem controles com validadores.
mmied
7

É assim que faço Angular 8:

Obtenha uma referência local do seu formulário:

<form name="myForm" #myForm="ngForm"></form>
@ViewChild('myForm', {static: false}) myForm: NgForm;

E sempre que você precisar redefinir o formulário, chame o resetFormmétodo:

this.myForm.resetForm();

Você precisará FormsModulede @angular/formspara que funcione. Certifique-se de adicioná-lo às suas importações de módulo.

Sinandro
fonte
1
@ViewChildno Angular 8 precisa de 2 argumentos. @ViewChild('myForm', {static: false}) myForm: NgForm;
Tanzeel
6

Para o angular versão 4, você pode usar isto:

this.heroForm.reset();

Mas, você pode precisar de um valor inicial como:

ngOnChanges() {
 this.heroForm.reset({
  name: this.hero.name, //Or '' to empty initial value. 
  address: this.hero.addresses[0] || new Address()
 });
}

É importante resolver o problema de nulos em sua referência de objeto.

link de referência , Pesquise "redefinir os sinalizadores de formulário".

Lucas Selliach
fonte
Obrigado, está funcionando para mim. É isso que eu quero.
Dhaval Mistry,
1

Encontrei outra solução. É um pouco hacky, mas está amplamente disponível no mundo angular2.

Visto que a diretiva * ngIf remove o formulário e o recria, pode-se simplesmente adicionar um * ngIf ao formulário e ligá-lo a algum tipo de formSuccessfullySentvariável. => Isso irá recriar o formulário e, portanto, redefinir os status de controle de entrada.

Claro, você também deve limpar as variáveis ​​do modelo. Achei conveniente ter uma classe de modelo específica para meus campos de formulário. Desta forma, posso redefinir todos os campos tão simples quanto criar uma nova instância desta classe de modelo. :)

Benjamin Jesuiter
fonte
Adição: estou usando o AngularDart, que ainda não tem esse método de redefinição. Ou pelo menos não descobri agora. : D
Benjamin Jesuiter
Com RC.6, basta reinicializar o modelo de formulários. Se você mover a criação do modelo de formulários para um método, chamar esse método redefinirá o formulário.
Günter Zöchbauer
@ GünterZöchbauer Oh, ótimo! Mal posso esperar para ter esse recurso no Angular2 for Dart também! :) Porque minha abordagem é um problema: eu tenho uma lista de todos os elementos de entrada em meu formulário. Eu recebo isso via dart-nativa querySelectorAllem ngAfterViewInit. Eu uso esta lista para enfocar o próximo elemento de entrada em keydown.enter, em vez de enviar o formulário. Esta lista quebra ao usar ngIf para reinicializar o formulário. :(
Benjamin Jesuiter
OK, resolvi o problema. Posso consultar novamente as instâncias de InputElement ao redefinir meu modelo de formulário.
Benjamin Jesuiter
0

Hm, agora (23 de janeiro de 2017 com angular 2.4.3) fiz funcionar assim:

newHero() {
    return this.model = new Hero(42, 'APPLIED VALUE', '');
}
<button type="button" class="btn btn-default" (click)="heroForm.resetForm(newHero())">New Hero</button>
adrhc
fonte
0

O código abaixo funciona para mim no Angular 4

import { FormBuilder, FormGroup, Validators } from '@angular/forms';
export class RegisterComponent implements OnInit {
 registerForm: FormGroup; 

 constructor(private formBuilder: FormBuilder) { }   

 ngOnInit() {
    this.registerForm = this.formBuilder.group({
      empname: [''],
      empemail: ['']
    });
 }

 onRegister(){
    //sending data to server using http request
    this.registerForm.reset()
 }

}
Thavaprakash Swaminathan
fonte
0

this.myForm.reset ();

Isso é tudo o suficiente ... Você pode obter a saída desejada

Manikanta Sai
fonte
1
Adicione mais explicações de como essa linha de código resolve o problema
Sfili_81
0

Para redefinir o formulário completo após o envio, você pode usar reset () no Angular. O exemplo a seguir é implementado em Angular 8. Abaixo está um formulário de inscrição, no qual estamos recebendo e-mail como entrada.

<form class="form" id="subscribe-form" data-response-message-animation="slide-in-left" #subscribeForm="ngForm"
(ngSubmit)="subscribe(subscribeForm.value); subscribeForm.reset()">
<div class="input-group">
   <input type="email" name="email" id="sub_email" class="form-control rounded-circle-left"
      placeholder="Enter your email" required ngModel #email="ngModel" email>
   <div class="input-group-append">
      <button class="btn btn-rounded btn-dark" type="submit" id="register"
         [disabled]="!subscribeForm.valid">Register</button>
   </div>
</div>
</form>

Consulte o documento oficial: https://angular.io/guide/forms#show-and-hide-validation-error-messages .

Abhishek Aggarwal
fonte
-3
resetForm(){
    ObjectName = {};
}
Shivendra
fonte
Embora este código possa responder à pergunta, você deve adicionar uma explicação declarando por que / como ele resolve o problema.
BDL
não restaura as classes 'tocadas', 'prístinas', etc ... de volta aos seus valores originais.
Pac0
@Shivendra Isso pode funcionar especialmente para o seu problema, mas não é genérico. Você está tornando o seu objectvazio e não o form.
Tanzeel