Cómo usar formularios reactivos en Angular
Introducción
Angular ofrece dos formas de trabajar con formularios: formularios basados en plantillas y formularios reactivos (también conocidos como formularios basados en modelos). Los formularios basados en plantillas son la forma predeterminada de trabajar con formularios en Angular. Con formularios controlados por plantillas, las directivas de plantilla se utilizan para crear una representación interna del formulario. Con formularios reactivos, crea su propia representación de un formulario en la clase de componente.
Nota: Los formularios reactivos se introdujeron con Angular 2.
Estas son algunas de las ventajas de las formas reactivas:
- Uso de validadores personalizados
- Cambiar la validación dinámicamente
- Adición dinámica de campos de formulario
En este artículo, explorará cómo se pueden aplicar formularios reactivos a una aplicación Angular de ejemplo.
requisitos previos
Si desea seguir este artículo, necesitará:
- Node.js instalado localmente, lo que puede hacer siguiendo Cómo instalar Node.js y crear un entorno de desarrollo local.
Esta publicación asume que tienes algunos conocimientos básicos de Angular.
Esta publicación también asume que está construyendo a partir de un proyecto Angular nuevo generado por @angular/cli
. Puede consultar esta publicación si está comenzando con Angular CLI.
Este tutorial se verificó con Node v15.1.0, npm
v6.14.8, @angular/core
v11.0.0 y @angular/forms
v11 .0.0.
Paso 1: Configuración del proyecto
A los efectos de este tutorial, compilará a partir de un proyecto Angular predeterminado generado con @angular/cli
.
- npx @angular/cli new angular-reactive-forms-example --style=css --routing=false --skip-tests
Esto configurará un nuevo proyecto Angular con estilos establecidos en \CSS (a diferencia de \Sass, Less o \Stylus), sin enrutamiento y pruebas de omisión.
Navegue al directorio del proyecto recién creado:
- cd angular-reactive-forms-example
Para trabajar con formularios reactivos, utilizará el ReactiveFormsModule
en lugar del FormsModule
.
Abra app.module.ts
en su editor de código y agregue ReactiveFormsModule
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
En este punto, debería tener un nuevo proyecto Angular con ReactiveFormsModule
.
Paso 2: agregar un formulario a la plantilla del componente
Con formas reactivas, la lógica se declara completamente en la clase de componente.
Abra app.component.html
en su editor de código y agregue las siguientes líneas de código:
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
<div>
<label>
Name:
<input formControlName="name" placeholder="Your name">
</label>
</div>
<div>
<label>
Email:
<input formControlName="email" placeholder="Your email">
</label>
</div>
<div>
<label>
Message:
<input formControlName="message" placeholder="Your message">
</label>
</div>
<button type="submit">Send</button>
</form>
Este código creará un formulario con tres campos: enviar
con la etiqueta Enviar
. Al enviar el formulario, se llamará al método onSubmit(myForm)
.
Nota: si está utilizando Angular 2.x, también debe agregar la directiva novalidate
con la etiqueta de apertura form
, ya que Angular anula la validación de HTML5. Con Angular 4+, novalidate
se agrega automáticamente detrás de escena.
Vamos a desglosarlo:
formGroup
: El formulario será tratado como unFormGroup
en la clase del componente, por lo que la directivaformGroup
permite dar un nombre al formar grupo.ngSubmit
: este es el evento que se activará al enviar el formulario.formControlName
: cada campo de formulario debe tener una directivaformControlName
con un valor que será el nombre utilizado en la clase del componente.
En este punto, debería tener un nuevo proyecto Angular con una plantilla de componente que usa un formulario.
Paso 3: Creación de la clase de componente
A continuación, en la clase de componente, definirá el FormGroup
y los FormControl
individuales dentro del FormGroup
.
Si se proporciona un valor al nueva un FormControl
, se utilizará como valor inicial para el campo.
Observe cómo los nombres FormGroup
y FormControl
son los mismos que se usaron en la plantilla. También observe cómo inicializa el FormGroup
en el gancho del ciclo de vida ngOnInit
:
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
myForm: FormGroup;
ngOnInit() {
this.myForm = new FormGroup({
name: new FormControl('Sammy'),
email: new FormControl(''),
message: new FormControl('')
});
}
onSubmit(form: FormGroup) {
console.log('Valid?', form.valid); // true or false
console.log('Name', form.value.name);
console.log('Email', form.value.email);
console.log('Message', form.value.message);
}
}
A los efectos de este tutorial, el método onSubmit
en realidad no comunica los valores del formulario enviado a ningún servicio o servidor externo. Sirve para mostrar cómo puede acceder a la validez del formulario y los valores de FormControl
.
En este punto, puede compilar su aplicación y abrirla en un navegador web. Después de ingresar valores para name
, email
y message
y presionar Enviar, el registro de la consola mostrará los valores.
Paso 4: Actualizar la clase de componente para usar FormBuilder
La construcción del formulario ngOnInit
se puede reescribir con el ayudante FormBuilder
. Esto le permite renunciar a todas las nuevas del grupo de formularios y controles de formulario.
Vuelva a visitar app.component.ts
en su editor de código y elimine FormControl
y reemplace FormGroup
con FormBuilder
:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
name: 'Sammy',
email: '',
message: ''
});
}
onSubmit(form: FormGroup) {
console.log('Valid?', form.valid); // true or false
console.log('Name', form.value.name);
console.log('Email', form.value.email);
console.log('Message', form.value.message);
}
}
Este código con FormBuilder
reduce la cantidad de código repetitivo para crear un FormGroup
.
Paso 5: Actualizar la clase de componente para usar validadores
Agregue la clase Validators
a sus importaciones y declare sus controles de formulario con matrices en lugar de simples valores de cadena.
El primer valor en la matriz es el valor del formulario inicial y el segundo valor es para que lo usen los validadores. Observe cómo se pueden usar varios validadores en el mismo control de formulario envolviéndolos en una matriz.
Vuelva a visitar app.component.ts
en su editor de código y agregue Validators
:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
name: ['Sammy', Validators.required],
email: ['', [Validators.required, Validators.email]],
message: ['', [Validators.required, Validators.minLength(15)]],
});
}
onSubmit(form: FormGroup) {
console.log('Valid?', form.valid); // true or false
console.log('Name', form.value.name);
console.log('Email', form.value.email);
console.log('Message', form.value.message);
}
}
Este código agrega requerido
a los campos name
, email
y message
. También garantiza que el valor de email
utilice el formato de una dirección de correo electrónico válida. También garantiza que el valor de message
tenga al menos 15 caracteres.
Si alguno de estos requisitos de formulario no se cumple, el valor valid
será false
. Si se cumplen todos estos requisitos de formulario, el valor valid
será true
.
Paso 6: Acceso al valor y la validez del formulario en la plantilla
En la plantilla, puede acceder al valor y la validez de cada FormControl
y al valor y la validez de todo el grupo de formularios como un todo.
Vuelva a visitar app.component.html
y use *ngIf
para mostrar mensajes de comentarios al usuario si los valores del formulario no son válidos:
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
<div>
<label>
Name:
<input formControlName="name" placeholder="Your name">
</label>
<div *ngIf="myForm.get('name').invalid && (myForm.get('name').dirty || myForm.get('name').touched)">
Please provide a name.
</div>
</div>
<div>
<label>
Email:
<input formControlName="email" placeholder="Your email">
</label>
<div *ngIf="myForm.get('email').invalid && (myForm.get('email').dirty || myForm.get('email').touched)">
Please provide a valid email address.
</div>
</div>
<div>
<label>
Message:
<input formControlName="message" placeholder="Your message">
</label>
<div *ngIf="myForm.get('message').invalid && (myForm.get('message').dirty || myForm.get('message').touched)">
Messages must be at least 15 characters long.
</div>
</div>
<button type="submit" [disabled]="myForm.invalid">Send</button>
</form>
Este código comprueba si el usuario ha interactuado con el campo (sucio
o tocado
). Luego, si el valor no pasa los requisitos de validación, mostrará el mensaje de error. El botón Enviar también se desactivará hasta que se resuelvan todos los problemas con los valores del formulario.
Hay varias formas de recuperar valores de control de formulario. Este ejemplo usa myForm.get(name)
que es equivalente a myForm.controls.name
. Es posible recuperar información de error con .hasError(requerido)
o .errors.required
.
Conclusión
En este artículo, exploró cómo se pueden aplicar formularios reactivos a una aplicación Angular de ejemplo. Usaste FormControl
, FormGroup
, FormBuilder
y Validators
para construir un formulario de ejemplo con validación. Para funcionalidad adicional, consulte la documentación oficial.
Si desea obtener más información sobre Angular, consulte nuestra página de temas de Angular para ver ejercicios y proyectos de programación.