Cómo implementar formularios en Angular: ¿reactivos o manejados por plantillas?

Todos los que hemos trabajado en aplicaciones web (con Angular o con cualquier otro framework SPA) nos hemos encontrado con la necesidad de implementar formularios más o menos complejos.

En este post vamos a analizar separadamente dos maneras distintas de trabajar formularios en Angular, sobre todo después de que, en las últimas actualizaciones, nos han dejado bien claro que son dos técnicas que pueden seguir viviendo juntas pero no mezcladas. ¿En qué consiste cada una?

Formularios reactivos (Angular Reactive Forms)

Si partimos de que existen dos maneras de hacer un trabajo: hacerlo bien o hacerlo rápidamente, hacerlo bien significa trabajar con formularios reactivos.

En el desarrollo con formularios reactivos, las acciones sobre los datos y los elementos html (el DOM) ocurren principalmente a nivel del componente (código typescript):

  • Declaración del formulario como objeto.
  • Declaración de cada uno de los elementos del formulario (y asociación de los mismos al objeto formulario).
  • Importación de componentes de validación.
  • Asignación de valores a inputs.
  • Asignación de métodos de validación a inputs.
  • Modificación de propiedades de los elementos html (como errores, propiedades o atributos).
  • Modificación de las propiedades de los objetos formulario.
  • Y elementos de formulario.

Otro aspecto Importante es que los formularios reactivos nos permiten exponer observables RxJS, que podemos enganchar con los observables expuestos por otros elementos del framework (el módulo HTTP, librerías de estado como NGRX, de modales, etc) y resolver así procesos asíncronos complejos de forma sencilla y controlada, al estilo reactivo. Es una de las características que potencia a Angular actualmente, nadie más lo hace de esta manera.

Es necesario destacar que todas estas ventajas tienen un coste: invertir más tiempo en planificar el desarrollo para convertirlo en un desarrollo funcional y así poder sacar provecho de la flexibilidad que nos ofrece.

En un desarrollo funcional (functional programming) los formularios reactivos son el camino a seguir principalmente porque no tienen enlace con los datos (data binding).

Por el contrario, utilizan lo que llamamos modelo de datos inmutable (inmutable data model), lo que nos da mucho más control/responsabilidad sobre el flujo de los datos.

Esta flexibilidad se refiere básicamente a que es posible desarrollar artefactos personalizados y modificar su comportamiento reactivamente en tiempo de ejecución: agregar componentes, modificar validaciones, modificar manejadores de eventos (event handlers), manejar eventos asíncronamente.

Por consiguiente, mayor tiempo invertido en analizar posibles escenarios, desarrollar métodos, y realizar pruebas. También es cierto que al manejar la mayor parte de la lógica en el componente (archivos ts), se reduce significativamente la lógica en la plantilla (archivos html).

Formularios desde templates (Angular Template Driven Forms)

Supongamos que necesitamos hacer un desarrollo relativamente sencillo, ¿es necesario añadir tanto nivel de complejidad para poder disfrutar de las bondades de Angular? No, no es necesario.

Gracias a los formularios manejados por plantillas (Template Driven Forms) es posible desarrollarlos en Angular manteniendo el principio KISS (acrónimo de Keep It Simple Stupid).

El desarrollo utilizando formularios manejados por plantillas es bastante sencillo: básicamente consiste en enlazar los datos (data binding) desde el componente (código typescript) hasta la plantilla (código html) a través de la sintaxis [(nombreDeVariable)] en cada elemento html a enlazar.

Este desarrollo funciona para escenarios simples, pero falla para escenarios más complejos debido a que la mayoría de las decisiones sobre el  comportamiento e interacción entre la lógica del componente y la plantilla html son tomadas internamente por Angular y no es posible modificarlas, no es flexible como lo es el desarrollo de formularios reactivos.

El código en el componente es mínimo en comparación a la cantidad de código que requerimos para resolver el mismo requerimiento utilizando formularios reactivos.

Por citar un caso específico, para modificar el valor de un elemento html desde el componente, no se requiere código alguno. Al utilizar la sintaxis [(nombreDeVariable)] los valores se mantienen sincronizados automáticamente.

Falla para escenarios más complejos porque en caso de necesitar modificar el comportamiento de un elemento del formulario en tiempo de ejecución se hace complejo y rebuscado.

Realizar pruebas unitarias en un desarrollo de este tipo representa un reto significativo.

Conclusión

Si abordamos un proyecto complejo y no tenemos problema en dedicar algo de tiempo en planear detalladamente y desarrollar nuestros propios métodos para interactuar con el html Formularios Reactivos es la mejor opción.

Si tenemos experiencia en las primeras versiones de Angular, estamos ante un requerimiento relativamente sencillo y queremos disfrutar de las maravillas del enlace de datos en doble sentido (two way data binding) Formularios Manejados por Plantillas son el camino a seguir.

De todos modos, pienso que usar formularios reactivos es la mejor manera a seguir, por muy tentador que sea disfrutar de lo práctico que nos ofrecen los formularios manejados por plantillas.

Los formularios reactivos nos facilitan la creación de tests unitarios (TDD for the win) y, lo más importante, nos permiten controlar ampliamente el flujo de la aplicación. Pero claro también podríais decir que soy un poco controlador ;)

Comentarios

  1. Norelis dice:

    Excelente articulo

Escribe un comentario