Signal Forms Parte 1: Conceptos básicos
Que es y porque Signals Forms
Siguiendo el enfoque de programación reactiva, el equipo de Angular a cambiado la forma en como se realizan los formularios en Angular. Con el lanzamiento de la versión 21.0, se ha lanzado también una versión preliminar de los formularios con signals. Para angular un Signal es "un contenedor que rodea un valor y notifica a los consumidores interesados cuando este cambia" (angular.dev). Esto ha facilitado la gestión de estados y datos reactivos en toda la plataforma, evitando el uso de rxjs en la mayoría del proyecto. La implementación de signal ahora a los formularios, dará como resultado un uso mas reactivo y organizado de los formularios, por lo que podemos tener un resultado mas preciso y confiable que el sistema anterior de formularios.
Concepto técnico
Signal Form en el momento que se escribe este articulo solo se deberá usar en un entorno de pruebas y desarrollo, ya que no es la versión final y puede cambiar cuando se lance en definitivo. Teniendo esto en cuenta, se puede implementar de la siguiente manera:
Definir una interface
Este es un cambio fundamental. Ahora se debe de crear primero una estructura con la cual vas a crear el formulario. Puede generar mas archivos en el desarrollo pero ayuda a estructurar la información que vamos a obtener del formulario. Para el caso que vamos a realizar seria lo siguiente:
export interface FormBlogData {
// Datos personales
nombre: string;
email: string;
telefono: string;
fechaNacimiento: string;
pais: string;
// Seguridad de la cuenta
contrasena: string;
confirmarContrasena: string;
}
Crear modelo
En base a la estructura anterior creamos un modelo inicial con valores predeterminados. Podemos añadir cualquier valor según convenga a nuestro formulario.
formBlogModel = signal<FormBlogData>({
// Datos personales
nombre: '',
email: '',
telefono: '',
fechaNacimiento: '',
pais: '',
// Gestión de direcciones
direcciones: [],
// Seguridad de la cuenta
contrasena: '',
confirmarContrasena: '',
});
Implementación en el HTML
Antes de realizar cambios en el html, es necesario importar la propiedad 'Field' para que los inputs detecten la configuración del formulario
@Component({
selector: 'app-form-blog-1',
imports: [Field],
templateUrl: './form-blog-1.html',
styleUrl: './form-blog-1.scss',
})
A continuación, demos de referenciarlo de la siguiente manera:
<form>
<h2>Datos Personales</h2>
<div>
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" [field]="form.nombre" />
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" [field]="form.email" />
</div>
<div>
<label for="telefono">Teléfono:</label>
<input type="tel" id="telefono" [field]="form.telefono" />
</div>
<div>
<label for="fechaNacimiento">Fecha de Nacimiento:</label>
<input type="date" id="fechaNacimiento" [field]="form.fechaNacimiento" />
</div>
<div>
<label for="pais">País:</label>
<select id="pais" [field]="form.pais">
<option value="">Seleccione un país</option>
<option value="mexico">México</option>
<option value="colombia">Colombia</option>
<option value="argentina">Argentina</option>
<option value="espana">España</option>
</select>
</div>
<h2>Seguridad de la Cuenta</h2>
<div>
<label for="contrasena">Contraseña:</label>
<input type="password" id="contrasena" [field]="form.contrasena" />
</div>
<div>
<label for="confirmarContrasena">Confirmar Contraseña:</label>
<input type="password" id="confirmarContrasena" [field]="form.confirmarContrasena" />
</div>
<button type="submit">Enviar</button>
</form>Obtener y setear datos
Luego de toda la configuración, ya llega la parte de como enviamos datos al formulario y como recuperamos datos del formulario. De manera similar como se hace con signals, se codifica de esta manera:
//Setear datos
setDataForm() {
this.formBlogModel.set({
nombre: 'Juan Pérez',
email: 'juan.perez@example.com',
telefono: '1234567890',
fechaNacimiento: '1990-01-01',
pais: 'mexico',
direcciones: [],
contrasena: 'password123',
confirmarContrasena: 'password123',
});
}
//Obtener datos
save() {
const nombre = this.form.nombre().value();
const email = this.form.email().value();
const telefono = this.form.telefono().value();
const fechaNacimiento = this.form.fechaNacimiento().value();
const pais = this.form.pais().value();
const direcciones = this.form.direcciones().value();
const contrasena = this.form.contrasena().value();
const confirmarContrasena = this.form.confirmarContrasena().value();
console.log({
nombre,
email,
telefono,
fechaNacimiento,
pais,
direcciones,
contrasena,
confirmarContrasena,
});
}
}De esta manera podemos tener una configuración básica de Signal Form. Luego de esto vamos a tener varios artículos donde se explicará como funciona la parte de las validaciones y que otras formas podemos crear formularios en angular 21.
Prompt IA para Generación de Componente Angular con Signals Forms
Genera un componente standalone de Angular que implemente un formulario de registro completo utilizando la funcionalidad de Signals Forms (versión preliminar). El objetivo es demostrar la definición del modelo, el binding en el template, el seteado de datos y la obtención de valores.
El componente debe llamarse
App(selectorapp-root) y debe ser una clase standalone (@Componentcontemplateystyleinline, y sinstandalone: trueexplícito, priorizando la estructura moderna de Angular).Requisitos Estructurales:
Interface de Datos: Define y exporta la interfaz TypeScript
FormBlogDatacon las siguientes propiedades:
nombre: string
email: string
telefono: string
fechaNacimiento: string
pais: string
contrasena: string
confirmarContrasena: stringModelo del Formulario: Inicializa la variable de clase
formBlogModelcomo unsignal<FormBlogData>con valores iniciales vacíos.Importaciones: Importa las propiedades necesarias para Signals Forms. Asume que la directiva de binding es
Fieldy que se debe importar desde la ruta simulada@angular/forms/signals. (Nota: para evitar errores de compilación, usa comentarios si la importación no es real).Template (HTML):
Crea una estructura de formulario estético y responsivo (usando clases de Tailwind CSS) para una "Cuenta de Usuario".
Incluye todos los campos de
FormBlogData. Utiliza un<select>parapaiscon opciones de ejemplo ("México", "Colombia", "Argentina", "España").Realiza el binding de los inputs/selects usando la directiva
[field], enlazándolos directamente al signal (ej:[field]="formBlogModel.nombre").Métodos de Datos y Lógica:
Implementa
setDataForm(): Un método que usethis.formBlogModel.set({...})para prellenar todos los campos del formulario con datos de ejemplo.Implementa
save(): Un método que se ejecute al enviar el formulario (o al hacer clic en un botón) que acceda a los valores de cada campo individualmente usando el patrónthis.formBlogModel.<field>().value()y luego imprima un objeto JSON con todos los datos en la consola.Añade dos botones en el UI: "Llenar con Datos de Ejemplo" (llama a
setDataForm) y "Enviar Formulario" (llama asave).Estilo (CSS): Utiliza un diseño de tarjeta (
card) centrado y limpio con estilos modernos de Tailwind CSS, asegurando buena legibilidad y espaciado.