Como Criar Sua Primeira Forma Angular Reativa
Você sabe como criar um formulário reativo Angular? Leia esta postagem do blog para saber tudo sobre o processo. Etapas detalhadas incluídas. Saiba Mais.
Você sabe como criar uma forma Angular Reativa? De fábrica, Angular nos oferece dois tipos de formas:
- Formulários Baseados em Modelos
- Formas Reativas
Em Formulários Orientados por Templates, você cria controles no template de componente e vincula os dados usando ngModel. Com esses, você não cria controles, objetos de formulário ou escreve código para trabalhar com o push e o pull de dados entre a classe componente e o template; Angular faz todas essas tarefas para você. Em formulários baseados em templates, há muito pouco código para validações na classe component, e eles são assíncronos.
No Reactive Forms, você cria controles de formulário como árvores de objetos na classe componente e os vincula aos controles nativos do formulário no template. Todas as validações e a criação dos controles de formulário são escritas na classe component. No Reactive Forms, todas as validações e mudanças no estado dos formulários nativos são síncronas, então você pode escrever código na classe component para observá-los. Você deve escolher criar formulários reativos quando o modelo de dados for imutável e geralmente mapeado para um banco de dados.
Qual a principal diferença entre essas duas abordagens para criar formulários? Em formulários reativos, você não usa diretivas como ngModel, required, etc. Você cria todos os controles e suas validações na classe component. Formulários reativos são fáceis de testar e manter, então neste post aprenderemos a criar um formulário reativo básico, usando FormControl, FormGroup, classe FormBuilder e adicionando validações.
Passo 1: Adicionar Módulo de Formas Reativas
Para começar a trabalhar com formulários reativos, primeiro adicione o ReactiveFormsModle no Módulo do Aplicativo, conforme mostrado na próxima listagem:
import {ReactiveFormsModule} from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Passo 2: Importar o módulo necessário no Componente
Em seguida, você precisa importar as classes reativas necessárias, como FormGroup, FormControl, FormArray, na classe components. Usaremos essas classes para construir nosso formulário reativo. Após importar essas classes, a classe component deve se apresentar como a listagem abaixo:
import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Reactive Forms Demo';
}
Sua classe componente pode ser diferente do AppComponent criado acima, dependendo da sua implementação; no entanto, aqui importamos classes FormGroup, FormControl e FormArray. Vamos aprender sobre essas classes uma a uma:
Passo 3: Usando a classe FormControl
A classe FormControl corresponde a um controle de forma individual, acompanhando seu valor e validade. Ao criar sua forma reativa, você criará um objeto da classe FormControl. O construtor FormControl assume três parâmetros:
- Valor inicial dos dados, que pode ser nulo.
- Array de validadores síncronos. Este é um parâmetro opcional.
- Array de validadores assíncronos. Este é um parâmetro opcional.
Na classe component, você pode criar um FormControl conforme mostrado na lista abaixo:
export class AppComponent {
email = new FormControl('');
}
Não estamos passando nenhum parâmetro opcional como validações de sincronização ou assíncronas, mas exploraremos esses parâmetros ao adicionar validação a um FormControl.
Na Visualização, você pode usar o FormControl por e-mail, conforme mostrado abaixo:
<input [formControl]='email'
type="text"
placeholder="Enter Email" />
{{email.value | json}}
Como você vê, estamos usando o property binding para vincular o e-mail formControl ao elemento de entrada na visualização.
Passo 4: Usando a classe FormGroup
FormGroup é um grupo de FormControls. Você pode encapsular vários FormControls dentro de um FormGroup, que oferece uma API para:
- Acompanhamento da validação de um grupo de controles ou formulários
- Acompanhamento do valor do grupo de controles ou forma
Ele contém controles filhos como sua propriedade e corresponde à forma de alavanca superior na visualização. Você pode pensar em um FormGroup como um único objeto, que agrega os valores do FormControl filho. Cada controle de forma individual é propriedade do objeto FormGroup.
Você pode criar uma classe FormGroup conforme mostrado na próxima listagem:
loginForm = new FormGroup({
email: new FormControl(' '),
password: new FormControl(' ')
})
Aqui criamos um formulário de login, que é um FormGroup. Ele consiste em dois controles de formulário para e-mail e senha. É muito fácil usar um FormGroup na visualização, como mostrado na próxima listagem:
<form [formGroup]='loginForm' novalidate class="form">
<input formControlName='email'
type="text"
class="form-control"
placeholder="Enter Email" />
<input formControlName='password'
type="password"
class="form-control"
placeholder="Enter Password" />
</form>
{{loginForm.value | json}}
{{loginForm.status | json }}
Aqui estamos usando o property binding para vincular seu FormGroup com a forma e a diretiva formControlName para anexar o FormControl a um elemento específico na visualização.
Se você usou um formulário baseado em templates, notará que a visualização agora é muito mais enxuta: não há ngModel ou nome associado aos elementos. Você pode encontrar o valor e o status do formulário usando a propriedade value e status. Agora, você não precisa mais usar a variável de referência template para encontrar status e valor do formulário.
Passo 5: Envio do Formulário
Para enviar o formulário, vamos adicionar um botão de envio no formulário e uma função a ser chamada. Vamos modificar o formulário conforme segue:
<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
<input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
<input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
<button class="btn btn-default">Login</button>
</form>
Na classe componente , você pode adicionar uma função para enviar o formulário conforme mostrado na lista abaixo:
export class AppComponent implements OnInit {
loginForm: FormGroup;
ngOnInit() {
this.loginForm = new FormGroup({
email: new FormControl(null, Validators.required),
password: new FormControl()
});
}
loginUser() {
console.log(this.loginForm.status);
console.log(this.loginForm.value);
}
}
Aqui acabamos de adicionar uma função chamada loginUser para gerenciar o evento de envio de formulário. Dentro dessa função, você pode ler o valor e o status do objeto FormGroup loginForm usando as propriedades status e value. Como você pode ver, isso te dá um objeto que agrega os valores dos controles individuais do formulário.
Step 6: Adding validations
Você deve ter notado que não adicionamos nenhuma validação aos formulários. Vamos começar adicionando uma validação ao FormControls. Para isso, importe os Validadores de @angular/forms:
ngOnInit() {
this.loginForm = new FormGroup({
email: new FormControl(null, Validators.required),
password: new FormControl(null, [Validators.required, Validators.maxLength(8)])
});
}
No modelo, você pode usar o método get do FormGroup para encontrar um erro em um controle de formulário específico e usá-lo. Na lista abaixo, estamos verificando o erro de validação de um e-mail e exibindo o div de erro.
<div class="alert alert-danger"
*ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
Email is required
</div>
Você também pode desativar o botão de enviar por padrão e ativá-lo quando o formulário for válido para permitir o envio. Isso pode ser feito conforme mostrado na listagem abaixo:
<button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
Juntando tudo, o template com formulários reativos ficará assim:
<div class="container">
<br />
<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
<input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
<div class="alert alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
Email is required
</div>
<input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
<div class="alert alert-danger" *ngIf=" !loginForm.get('password').valid && loginForm.get('email').touched">
Password is required and should less than 10 characters
</div>
<button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
</form>
</div>
A classe componente será conforme mostrada na listagem abaixo:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
loginForm: FormGroup;
ngOnInit() {
this.loginForm = new FormGroup({
email: new FormControl(null, [Validators.required, Validators.minLength(4)]),
password: new FormControl(null, [Validators.required, Validators.maxLength(8)])
});
}
loginUser() {
console.log(this.loginForm.status);
console.log(this.loginForm.value);
}
}
Step 7: Using FormBuilder
O FormBuilder é usado para simplificar a sintaxe do FormGroup e do FormControl. Isso é muito útil quando seu formulário fica longo. Let; s refatore loginForm para usar o FormBuilder. Para isso, primeiro importe o FormBuilder de @angular/forms. Depois, injete-o no componente conforme mostrado na lista abaixo:
constructor(private fb : FormBuilder){}
Você pode usar o FormBuilder para criar um formulário reativo, como mostrado na listagem abaixo. Como você vê, ele simplificou a sintaxe:
this.loginForm = this.fb.group({
email: [null, [Validators.required, Validators.minLength(4)]],
password: [null, [Validators.required, Validators.maxLength(8)]]
})
O template será o mesmo para as classes FormBuilder e FormControl. Juntando tudo, o componente que usa o FormBuilder para criar um formulário reativo ficará assim:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators, FormBuilder } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
loginForm: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.loginForm = this.fb.group({
email: [null, [Validators.required, Validators.minLength(4)]],
password: [null, [Validators.required, Validators.maxLength(8)]]
})
}
loginUser() {
console.log(this.loginForm.status);
console.log(this.loginForm.value);
}
}
Gostou deste post?
E aí está! Se você gostou deste post, por favor, compartilhe-o. Além disso, se você ainda não fez check-out Infragistics Ignite UI for Angular Componentes, certifique-se de fazê-lo! Eles têm 30+ componentes de Angular baseados em material para ajudá-lo a codificar aplicativos da web rápidos com mais rapidez.
