Vamos a finalizar la presentación de las direcciones donde lo dejamos en la anterior publicación en el último apartado, recordemos que teníamos que resolver la presentación de las direcciones (CbAddresses) al crear una nuevo cliente (CbCustomer) ya que con el desarrollo inicial no era posible, esta fue la solución planteada:
- Crear siempre una entidad CbAddresses al crear cada nuevo cliente.
- Ocultar a nivel de creación las direcciones hasta que exista un CbAddresses asociado el cliente, y así, tener un funcionamiento correcto.
OpenXava Fin de la primera parte
Definiendo vistas diferentes para crear y actualizar la entidad para mejorar la presentación siguiendo la extensa documentación proporcionada por OpenXava en este caso en el OpenXava How to.Código Xules
1. Crear siempre una entidad CbAddresses al crear cada nuevo cliente
Vamos a repasar lo explicado al final del capítulo anterior para así tener una visión completa del problema planteado. Empezamos recordando la creación de retrollamadas de OpenXava, esto nos permitirá obtener un funcionamiento más o menos correcto, dejando la creación de las direcciones del cliente para después de su creación ya que no se podrán añadir hasta que el cliente haya sido creado, pero si después, ya que en la creación le vamos a asociar al cliente un idaddresses de la entidad CbAddresses automáticamente, veamos como.
Con @PreCreate se pueden marcar métodos que serán ejecutados antes de persistir algún objeto, en nuestro caso antes de crear CbCustomer nos interesa crear un CbAddresses que se le asignará así automáticamente al cliente CbCustomer. Ahora definimos el método dentro de la clase CbCustomer que vamos a utilizar:
/** * Cuando creamos el cliente creamos la entidad de CbAddresses que lleva * asociada, para que después se pueda añadir la dirección al actualizar * el cliente. */ @PreCreate public void onPreCreate() { if (getCbAddresses() == null) { CbAddresses cbAddressesAux = new CbAddresses(); cbAddressesAux = XPersistence.getManager().merge(cbAddressesAux); setCbAddresses(cbAddressesAux); } }
2. Ocultar a nivel de creación las direcciones
Lo que nos planteábamos para resolver nuestro problema era ocultar a nivel de creación las direcciones, hasta que exista un CbAddresses asociado el cliente, y así, tener un funcionamiento correcto.
Se puede deducir fácilmente que para conseguir esto vamos a tener que definir dos vistas diferentes una para Crear y otra para Actualizar, esto no lo podemos hacer directamente en las anotaciones y para ello tendremos que modificar el controlador usado por defecto y definir las clases donde les indiquemos las vistas a utilizar en cada caso.
Una vez llegada a esta conclusión la solución parece fácil, pero he de decir que no lo fue, ya que creí que no estaba utilizando correctamente @AsEmbedded, esto implica que vamos a crear un controlador propio, en esto profundizaré en la segunda parte del tutorial, pero ahora necesitamos resolver este problema, así que, lo vamos a explicar.
Del atolladero en que me encontraba me ayudó a salir la extensa y buena documentación de OpenXava, por casualidad consultando el OpenXava How to, llegué a la solución de mi problema en la segunda entrada ¿Cómo usar una vista diferente para crear y para actualizar?, siguiendo sus instrucciones elaboré la mía.
Definimos las vistas diferenciadas
Tenemos que definir un vista para crear y otra para actualizar:
@Views({ @View(name="Crear", members=" .... "), @View(name="Actualizar", members=" ... ") }) public class MiEntidad { ...
Lo que buscamos es no tener en la vista de creación (Crear) la dirección representada por CbAddresses, y si tenerla en la vista de actualización (Actualizar), para ello definimos así las nuevas vista:
@Entity @Views({ @View( name="Crear", members = // Vista que usamos para crear el cliente sin la dirección (CbAddresses) "customer;" + "customername;" + "cbEnterprise;" + "customeralias;" + "contact;" + "sale, customerpayer, cbPaymentmethod; " + "customerstate;" + "identitynumber;" + "cbLanguage; cbCountry; cbCurrency;" ), @View( name="Actualizar", members = // Vista que vamos a utilizar cuando ya esté creado la entidad cliente para mostrar la dirección (CbAddress). "customer;" + "customername;" + "cbEnterprise;" + "customeralias;" + "contact;" + "sale, customerpayer, cbPaymentmethod; " + "customerstate;" + "identitynumber;" + "cbLanguage; cbCountry; cbCurrency;" + "cbAddresses;"), ... }) ... @Table(name = "cb_customer") public class CbCustomer {
Una vez creadas las vistas, donde la única diferencia es que en la de Crear no aparece + «cbAddresses;», necesitamos reflejar los cambios que queremos en nuestro controlador, y para eso, editamos el fichero controladores.xml.
La definición básica de un controlador es la siguiente:
<controladores> <var-entorno ... /> ... <!-- 1 --> <objeto ... /> ... <!-- 2 --> <controlador ... /> ... <!-- 3 --> </controladores>
- var-entorno (varias, opcional): variable que contienen información de configuración. Estas variables pueden ser accedidas desde las acciones y filtros, y su valor puede ser sobreescrito para cada módulo.
- objeto (varios, opcional): define objetos Java de sesión del usuario.
- controlador (varios, obligado):l os controladores son agrupaciones de acciones.
- nombre (obligatrio): Nombre del controlador en nuestro caso será: MiCustomerControlador .
- hereda-de (varios, opcional): permite usar herencia múltiple, aquí hacemos la herencia de Typical.
- accion (varios, obligada): Definición de la lógica a ejecutar cuando el usuario pulse un botón o vínculo. Aquí vamos a definir nuestras dos nuevas acciones: «new» y «search»
Si quieres saber más en la documentación de OpenXava Controladores se explica detalladamente, puedes ver todas la sintaxis de las acciones en el apartado Controlador y sus acciones, no voy a entrar más en detalle porque quería profundizar en este tema en la segunda parte de mi tutorial.
Finalmente, esto implicar refinar la acción new para escoger la vista Crear y la acción search para escoger la vista Actualizar. Primero, definamos nuestro propio controlador, en controladores.xml en la carpeta xava, así:
<controlador nombre="MiCustomerControlador"> <hereda-de controlador="Typical" /> <accion nombre="new" clase="org.xulescode.customerdb.actions.MiAccionNuevo" imagen="images/new.gif" al-iniciar="true" atajo-de-teclado="F2"> <usa-objeto nombre="xava_view" /> </accion> <accion nombre="search" por-defecto="si-posible" oculta="true" clase="org.xulescode.customerdb.actions.MiAccionBuscar" atajo-de-teclado="F8"> <usa-objeto nombre="xava_view" /> </accion> </controlador>
Asignamos el controlador al módulo
Y ahora asignamos este controlador a nuestro módulo, y definimos la acción de búsqueda para el módulo. Escribimos nuestro módulo de esta manera en aplicacion.xml en la carpeta xava:
<modulo nombre="CbCustomer"> <var-entorno nombre="XAVA_SEARCH_ACTION" valor="MiCustomerControlador.search" /> <modelo nombre="CbCustomer" /> <controlador nombre="MiCustomerControlador" /> </modulo>
Definimos la lógica de nuestras acciones
Una vez descrito el controlador y el módulo, vamos a escribir la lógica para las clases que hemos indicado, creamos un paquete separado para agrupara nuestras acciones org.xulescode.customerdb.actions. Para MiAccionBuscar vamos a escribir:
package org.xulescode.customerdb.actions; import org.openxava.actions.*; import java.util.*; public class MiAccionBuscar extends SearchByViewKeyAction { public void execute() throws Exception { Map clave = getView().getKeyValuesWithValue(); // 1 getView().setViewName("Actualizar"); // 2 getView().setValues(clave); // 3 super.execute(); } }
«Los valores de la clave se han de capturar (1) para que puedan ser restaurados (3) después de la inicialización que hace el método setViewName(…)«, así de claro lo explican en el OpenXava How to
Y para MiAccionNuevo:
package org.xulescode.customerdb.actions; import org.openxava.actions.*; public class MiAccionNuevo extends NewAction { public void execute() throws Exception { getView().setViewName("Crear"); super.execute(); } }
El resultado es el siguiente, al crear un nuevo cliente, se cargará la vista Crear y la pantalla se mostrará así:
Una vez creado podemos ir a editar el cliente, y añadir la dirección, con los cambios que hemos realizado se cargará la vista Actualizar con los datos de las direcciones:
Con esto doy por finalizado la primera parte del Tutorial OpenXava. Espero que te haya sido útil.Código Xules
Muy buenos tus tutoriales. Podrias ayudarnos con un tutorial de reportes personalizados imprimibles en OpenXava
Muchas gracias por tu valoración, tenía pensado continuar con el tutorial de OpenXava en Septiembre, donde entre otras cosas tengo pensado abordar el tema de informes personalizados con OpenXava.
Excelente tutorial; Estoy empezando con OpenXava y ésto creo que será un apoyo fundamental.
Muchas gracias Julio!!!
Muchas gracias por tu valoración Gonzalo, espero que sea un gran apoyo.
Un saludo.
Muchas gracias, esto es justo lo que necesitaba, llevaba un par de días peleándome con la actualización en una vista diferente.
Hola Guillermo.
Me alegro que te haya servido de ayuda.
Un saludo.