Introducción
Los formularios reactivos en Angular proporcionan una forma más robusta y escalable de manejar formularios en comparación con los formularios basados en plantillas. Utilizan una aproximación programática para construir y gestionar formularios, lo que permite un mayor control sobre la validación y el estado del formulario.
Conceptos Clave
- FormGroup: Representa un grupo de controles de formulario.
- FormControl: Representa un control individual de formulario.
- FormArray: Representa una matriz de controles de formulario.
- FormBuilder: Servicio que facilita la creación de instancias de FormGroup, FormControl y FormArray.
Configuración Inicial
Antes de comenzar, asegúrate de que el módulo ReactiveFormsModule
esté importado en tu módulo principal o en el módulo donde vayas a utilizar formularios reactivos.
import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ // otros módulos ReactiveFormsModule ], // otros metadatos }) export class AppModule { }
Creación de un Formulario Reactivo
Paso 1: Importar las Clases Necesarias
Primero, importa las clases necesarias desde @angular/forms
.
import { Component } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms';
Paso 2: Definir el Formulario en el Componente
Define el formulario en tu componente. Aquí hay un ejemplo de un formulario simple con dos campos: nombre y correo electrónico.
@Component({ selector: 'app-reactive-form', templateUrl: './reactive-form.component.html' }) export class ReactiveFormComponent { myForm: FormGroup; constructor() { this.myForm = new FormGroup({ name: new FormControl('', [Validators.required, Validators.minLength(3)]), email: new FormControl('', [Validators.required, Validators.email]) }); } onSubmit() { console.log(this.myForm.value); } }
Paso 3: Crear la Plantilla del Formulario
Crea la plantilla del formulario en el archivo HTML correspondiente.
<form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <label for="name">Nombre:</label> <input id="name" formControlName="name"> <div *ngIf="myForm.get('name').invalid && myForm.get('name').touched"> <small *ngIf="myForm.get('name').errors.required">El nombre es obligatorio.</small> <small *ngIf="myForm.get('name').errors.minlength">El nombre debe tener al menos 3 caracteres.</small> </div> <label for="email">Correo Electrónico:</label> <input id="email" formControlName="email"> <div *ngIf="myForm.get('email').invalid && myForm.get('email').touched"> <small *ngIf="myForm.get('email').errors.required">El correo electrónico es obligatorio.</small> <small *ngIf="myForm.get('email').errors.email">El correo electrónico no es válido.</small> </div> <button type="submit" [disabled]="myForm.invalid">Enviar</button> </form>
Validación de Formularios
La validación en formularios reactivos se maneja a través de validadores que se pueden aplicar a los controles de formulario. Angular proporciona varios validadores incorporados como Validators.required
, Validators.minLength
, Validators.maxLength
, Validators.email
, etc.
Validadores Personalizados
También puedes crear validadores personalizados. Aquí hay un ejemplo de un validador personalizado que verifica si un nombre contiene solo letras.
import { AbstractControl, ValidationErrors } from '@angular/forms'; export function onlyLettersValidator(control: AbstractControl): ValidationErrors | null { const valid = /^[a-zA-Z]+$/.test(control.value); return valid ? null : { onlyLetters: true }; }
Luego, puedes usar este validador en tu formulario.
this.myForm = new FormGroup({ name: new FormControl('', [Validators.required, Validators.minLength(3), onlyLettersValidator]), email: new FormControl('', [Validators.required, Validators.email]) });
Ejercicio Práctico
Ejercicio
Crea un formulario reactivo con los siguientes campos:
- Nombre de usuario (obligatorio, mínimo 5 caracteres)
- Contraseña (obligatorio, mínimo 8 caracteres)
- Confirmar contraseña (debe coincidir con la contraseña)
Solución
- Componente TypeScript
import { Component } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-signup-form', templateUrl: './signup-form.component.html' }) export class SignupFormComponent { signupForm: FormGroup; constructor() { this.signupForm = new FormGroup({ username: new FormControl('', [Validators.required, Validators.minLength(5)]), password: new FormControl('', [Validators.required, Validators.minLength(8)]), confirmPassword: new FormControl('', [Validators.required]) }, { validators: this.passwordMatchValidator }); } passwordMatchValidator(form: FormGroup) { return form.get('password').value === form.get('confirmPassword').value ? null : { mismatch: true }; } onSubmit() { console.log(this.signupForm.value); } }
- Plantilla HTML
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()"> <label for="username">Nombre de Usuario:</label> <input id="username" formControlName="username"> <div *ngIf="signupForm.get('username').invalid && signupForm.get('username').touched"> <small *ngIf="signupForm.get('username').errors.required">El nombre de usuario es obligatorio.</small> <small *ngIf="signupForm.get('username').errors.minlength">El nombre de usuario debe tener al menos 5 caracteres.</small> </div> <label for="password">Contraseña:</label> <input id="password" type="password" formControlName="password"> <div *ngIf="signupForm.get('password').invalid && signupForm.get('password').touched"> <small *ngIf="signupForm.get('password').errors.required">La contraseña es obligatoria.</small> <small *ngIf="signupForm.get('password').errors.minlength">La contraseña debe tener al menos 8 caracteres.</small> </div> <label for="confirmPassword">Confirmar Contraseña:</label> <input id="confirmPassword" type="password" formControlName="confirmPassword"> <div *ngIf="signupForm.errors?.mismatch && signupForm.get('confirmPassword').touched"> <small>Las contraseñas no coinciden.</small> </div> <button type="submit" [disabled]="signupForm.invalid">Registrarse</button> </form>
Conclusión
Los formularios reactivos en Angular proporcionan una forma poderosa y flexible de manejar formularios complejos. Al utilizar FormGroup
, FormControl
y validadores, puedes crear formularios robustos y altamente personalizables. En el siguiente tema, exploraremos la validación de formularios en mayor detalle, incluyendo validadores asíncronos y mensajes de error personalizados.
Curso de Angular 2+
Módulo 1: Introducción a Angular
- ¿Qué es Angular?
- Configuración del Entorno de Desarrollo
- Tu Primera Aplicación Angular
- Arquitectura de Angular
Módulo 2: Conceptos Básicos de TypeScript
- Introducción a TypeScript
- Variables y Tipos de Datos en TypeScript
- Funciones y Funciones Flecha
- Clases e Interfaces
Módulo 3: Componentes y Plantillas
- Creación de Componentes
- Plantillas de Componentes
- Estilos de Componentes
- Interacción entre Componentes
Módulo 4: Directivas y Pipes
Módulo 5: Servicios e Inyección de Dependencias
- Introducción a los Servicios
- Creación y Uso de Servicios
- Inyección de Dependencias
- Inyectores Jerárquicos
Módulo 6: Enrutamiento y Navegación
Módulo 7: Formularios en Angular
- Formularios Basados en Plantillas
- Formularios Reactivos
- Validación de Formularios
- Formularios Dinámicos
Módulo 8: Cliente HTTP y Observables
- Introducción al Cliente HTTP
- Realizando Solicitudes HTTP
- Manejo de Respuestas HTTP
- Uso de Observables
Módulo 9: Gestión de Estado
- Introducción a la Gestión de Estado
- Uso de Servicios para la Gestión de Estado
- NgRx Store
- NgRx Effects