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
