Angular 21 de Cero a Experto / Formularios
Formularios: template-driven vs reactivos
Los formularios son la puerta por la que entran los datos a tu app: crear un gasto, editar un perfil, iniciar sesión. Angular ofrece DOS formas de construirlos —template-driven y reactivos— y elegir bien marca la diferencia entre un formulario que se mantiene solo y uno que se vuelve un nudo. Hoy entiendes ambos enfoques, sus fortalezas, y por qué los reactivos son el estándar para todo lo que no sea trivial.
Dos formas de llevar las cuentas
Enfoque template-driven: la lógica vive en el HTML
Con el enfoque template-driven, el formulario se define en el template con directivas
(ngModel), y Angular construye el modelo por detrás. Es rápido para formularios pequeños:
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-login',
imports: [FormsModule], // ngModel vive aquí
template: `
<form #f="ngForm" (ngSubmit)="entrar()">
<input name="email" [(ngModel)]="email" required email />
<input name="clave" [(ngModel)]="clave" required minlength="6" />
<button [disabled]="f.invalid">Entrar</button>
</form>
`,
})
export class LoginComponent {
email = '';
clave = '';
entrar() { console.log(this.email, this.clave); }
}La validación se declara con atributos HTML (required, minlength), y #f="ngForm" te da
el estado del formulario. Es conciso, pero toda la lógica está atada al template: cuesta
testear, reutilizar validaciones y manejar formularios complejos o dinámicos.
Enfoque reactivo: el formulario es un objeto en tu clase
Con el enfoque reactivo, defines la estructura del formulario en la CLASE con objetos
(FormGroup, FormControl), y el template solo se conecta a ellos. El modelo es explícito,
tipado y testeable:
import { Component, inject } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
@Component({
selector: 'app-login',
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="entrar()">
<input formControlName="email" />
<input formControlName="clave" type="password" />
<button [disabled]="form.invalid">Entrar</button>
</form>
`,
})
export class LoginComponent {
private fb = inject(FormBuilder);
form = this.fb.group({
email: ['', [Validators.required, Validators.email]],
clave: ['', [Validators.required, Validators.minLength(6)]],
});
entrar() { console.log(this.form.value); }
}Aquí el formulario es un OBJETO (form) que vive en tu clase: puedes leerlo, validarlo,
transformarlo y testearlo sin tocar el DOM. La validación es código (arrays de validadores),
no atributos HTML. Esta separación es lo que hace a los reactivos escalar.
Cuándo cada uno
Un puente con lo que ya sabes
Si vienes de React, el enfoque reactivo te resultará familiar: es como manejar el estado del
formulario tú mismo con useState/React Hook Form (el modelo vive en tu código), mientras
que template-driven se parece más a los inputs no controlados con validación por atributos
HTML. La ventaja de Angular es que trae un sistema de formularios reactivos completo de
fábrica —validadores, estados, arrays dinámicos— sin instalar nada.
¿Por qué los formularios reactivos escalan mejor que los template-driven?
Mini-reto
Para cada formulario, decide qué enfoque usarías y por qué: 1) un campo de búsqueda en la barra superior; 2) el formulario de "nuevo gasto" con validación de monto positivo y categoría obligatoria; 3) un formulario de encuesta donde el número de preguntas cambia según respuestas anteriores; 4) un toggle de "modo oscuro". Anota cuál lógica de validación necesitaría cada uno.
Qué sigue
Elegiste el enfoque reactivo para lo que importa. La próxima lección lo construye a fondo:
FormGroup, FormControl y FormBuilder, con el tipado estricto que Angular moderno trae
de fábrica —para que el valor de tu formulario sea un objeto con tipos, no un any—.