Reutilización de formularios en varios sitios
En Nette, tienes varias opciones para reutilizar el mismo formulario en múltiples lugares sin duplicar código. En este artículo, repasaremos las diferentes soluciones, incluyendo las que deberías evitar.
Fábrica de formularios
Un enfoque básico para utilizar el mismo componente en múltiples lugares es crear un método o clase que genere el componente, y luego llamar a ese método en diferentes lugares de la aplicación. Este método o clase se llama factory. Por favor, no confundir con el patrón de diseño método de fábrica, que describe una forma específica de utilizar fábricas y no está relacionado con este tema.
Como ejemplo, vamos a crear una fábrica que construirá un formulario de edición:
Ahora puedes usar esta fábrica en diferentes lugares de tu aplicación, por ejemplo en presentadores o componentes. Y hacemos esto solicitándola como una dependencia. Así que primero, escribiremos la clase en el archivo de configuración:
Y luego la usamos en el presentador:
Puedes extender la fábrica de formularios con métodos adicionales para crear otros tipos de formularios que se adapten a tu aplicación. Y, por supuesto, puedes añadir un método que cree un formulario básico sin elementos, que utilizarán los demás métodos:
El método createForm()
no hace nada útil todavía, pero eso cambiará rápidamente.
Dependencias de fábrica
Con el tiempo, se hará evidente que necesitamos que los formularios sean multilingües. Esto significa que necesitamos
configurar un traductor para todos los formularios. Para ello,
modificamos la clase FormFactory
para que acepte el objeto Translator
como dependencia en el
constructor, y lo pase al formulario:
Como el método createForm()
también es llamado por otros métodos que crean formularios específicos, sólo
necesitamos establecer el traductor en ese método. Y ya está. No hay necesidad de cambiar ningún código de presentador
o componente, lo cual es genial.
Más clases de fábrica
Alternativamente, puede crear múltiples clases para cada formulario que desee utilizar en su aplicación. Este enfoque puede
aumentar la legibilidad del código y hacer que los formularios sean más fáciles de gestionar. Deje el original
FormFactory
para crear sólo un formulario puro con configuración básica (por ejemplo, con soporte de traducción)
y cree una nueva fábrica EditFormFactory
para el formulario de edición.
Es muy importante que la unión entre las clases FormFactory
y EditFormFactory
se implemente por composición, no por herencia de objetos:
Utilizar la herencia en este caso sería totalmente contraproducente. Se encontraría con problemas muy rápidamente. Por
ejemplo, si quisiera agregar parámetros al método create()
; PHP reportaría un error de que su firma es diferente a
la del padre. O al pasar una dependencia a la clase EditFormFactory
a través del constructor. Esto causaría lo que
llamamos el infierno del constructor.
En general, es mejor preferir la composición a la herencia.
Manejo de Formularios
El manejador de formularios que es llamado después de un envío exitoso también puede ser parte de una clase fábrica.
Funcionará pasando los datos enviados al modelo para su procesamiento. Devolverá cualquier error al formulario. El modelo en el
siguiente ejemplo está representado por la clase Facade
:
Deje que el presentador se encargue de la redirección. Añadirá otro manejador al evento onSuccess
, que
realizará la redirección. Esto permitirá utilizar el formulario en diferentes presentadores, y cada uno puede redirigir a una
ubicación diferente.
Esta solución aprovecha la propiedad de los formularios de que, cuando se llama a addError()
sobre un formulario
o su elemento, no se invoca al siguiente manejador onSuccess
.
Heredando de la clase Form
Un formulario creado no debe ser hijo de un formulario. En otras palabras, no utilice esta solución:
En lugar de construir el formulario en el constructor, utilice la fábrica.
Es importante darse cuenta de que la clase Form
es principalmente una herramienta para ensamblar un formulario, es
decir, un constructor de formularios. Y el formulario ensamblado puede considerarse su producto. Sin embargo, el producto no es un
caso específico del constructor; no existe una relación es a entre ellos, que constituye la base de la herencia.
Componente Form
Un enfoque completamente diferente es crear un componente que incluya un formulario. Esto da nuevas posibilidades, por ejemplo para renderizar el formulario de una manera específica, ya que el componente incluye una plantilla. O se pueden utilizar señales para la comunicación AJAX y cargar información en el formulario, por ejemplo para sugerencias, etc.
Vamos a crear una fábrica que producirá este componente. Basta con escribir su interfaz:
Y añadirla al fichero de configuración:
Y ahora podemos solicitar la fábrica y utilizarla en el presentador: