martes, 12 de junio de 2007

Organizando las vistas para Ajax

Siguiendo con el ejercicio anterior he descubierto unas cuantas cosas más. Por ejemplo, los problemas que supone la validación CakePHP interaccionando con un planteamiento "ajaxiano" de la vista.

La solución que he encontrado es la siguiente:

De lo general a lo particular

Lo primero sería hacer un croquis general de lo que voy a necesitar poner en la vista. En mi caso, por ejemplo, un título, un formulario y una tabla. Hay que tener en cuenta las partes que se van a tener que actualizar solas, en un momento dado, o las que habrá que actualizar globalmente.

Lo mejor parece ser descomponer la vista en partes, valorando si necesitan ser incluidas en una div, y crear elements para generar cada una de ellas. De este modo dispondremos de piezas de construcción para generar las vistas definitivas. Procura ponerles nombres bien descriptivos a los elementos.

Preparando las vistas

Con los elements ya preparados generamos las vistas que nos haga falta, aprovechando el método This::Element ('elemento').

La idea es crear tantas vistas como podamos necesitar. Intentaré explicarlo:

Normalmente la primera petición para cierta página será una petición normal, sin Ajax ni cosas raras. Entonces tendremos que tener una vista que muestre todo lo necesario. En mi ejemplo, una vista que muestre el título, el formulario y la tabla. Esa podría ser index.ctp, si mi acción es index.

Como mi tabla tiene enlaces Ajax para ordenar los resultados y éstos piden que se actualice sólo la div que contiene la tabla, necesitaré una vista que sólo muestre la tabla. La llamaré tabla.ctp.

El formulario envía una petición Ajax al servidor para añadir entradas sin actualizar toda la página. El resultado del formulario debería actualizar la tabla, pero puede ocurrir que tenga que actualizarse también el propio formulario, por ejemplo si hay errores en la validación en CakePHP. En este caso, podría crear una nueva plantilla, aunque veo que index.ctp me sirve para esto sin tener que duplicar el trabajo.

También podría preparar una vista específica para cuando se solicita la acción con una petición no Ajax.

Y luego están las vistas para las demás acciones que programemos, por supuesto. En ellas hay que considerar los mismos aspectos acerca de si es posible que sean solicitadas a través de Ajax y qué contenido deben proporcionar.

En el controlador

Ahora bien, en el controlador tenemos que determinar qué tipo de petición está entrando y qué contenido tenemos que devolver. Tenemos dos armas:

RequestHandler->isAjax() es el método que nos permite saber si la petición es Ajax y hacer cosas diferentes en cada caso.

Controller::Render ('vista') nos permite especificar una vista concreta con la que mostrar el resultado de la acción.

Usándolas en combinación, podemos hacer que nuestra acción sepa qué contenido debe entregar a la petición Ajax (o de cualquier otro tipo) y mediante qué vista.

No te olvides de generar el contenido

Eso sí, hay que tener presente qué contenido es el que vamos a actualizar, porque las cosas pueden ser un poco diferentes que en el uso normal.

Por ejemplo, en este caso de la combinación de formulario de entrada más tabla de datos, he decidido que al añadir una entrada hay que actualizar la vista que contiene tanto el formulario como la tabla. Por lo tanto, la acción add, cuando es llamada mediante Ajax, tiene que lidiar no sólo con tomar los datos y hacer lo que haga falta con ellos, sino también obtener el listado para mostrar como si fuera una acción index y enviárselos a la vista index, en vez de a la vista por defecto (add).

Alternativamente, la versión "no Ajax" de la acción podría usar una vista diferente y necesitar información diferente.

Otros beneficios

Algunas de las ideas expuestas aquí, aparte de ser útiles e incluso necesarias para integrar Ajax, tienen algunos beneficios colaterales.

Al descomponer una vista, o una familia de vistas, en elementos reutilizables es más fácil, por ejemplo tener un único formulario para añadir y editar. Estamos siguiendo eso que llaman la metodología DRY (Don't Repeat Yourself).

Otro beneficio es que si una parte de una vista es relativamente complicada, al empaquetarla en un element podemos mantener controlada esa complejidad.

No hay comentarios: