Control ChainedMenu con AJAX
De MorfeoWiki
Tabla de contenidos |
Sinopsis
Se trata de implementar el comportamiento del control menu encadenado con AJAX en el cliente. De esta forma, se disminuirá la carga de transferencia cada vez que se hace una llamada al servidor provocada por un evento disparado desde el menú encadenado. Por otro lado se mejorará la experiencia de usuario al aumentar la interacción con el control visual.
Implementación
- Añadir el método sendObject(RequestData data, Object data, String mimeType) a la interfaz IActionExecutor e implementar dicho método en la clase AbstractAdapter y toda las acciones que conlleve dicha implementación. Se ha de discutir los parámetros del método sendObject.
- Para esta implemetación, el Object que se intercambiará será un objeto que encapsulará un objeto JSON para su serialización. El mime-type correspondiente por lo tanto será application/json a la hora de enviar la respuesta al cliente y UTF-8 como encoding para la misma según RFC_4627.
Se ha comprobado que el mime-type application/json no es soportado por el navegador Opera Mobile, en su lugar se esta enviando text/plain que es soportado por Opera mobile, Internet Explorer Mobile y Minimo. Para Opera Mobile se mandará text/plain pero para el resto application/json, para ello se hará una excepción en el código para conocer si el dispositivos destinto es Opera Minimo o no.
- En primera aproximación (posible cambio si la experiencia en la implementación nos dice otra cosa) el objeto JSON estará formado por una lista de codes: y values: para construir el contenido que conformará la combo actual.
- En el motor de presentación, en el correspondiente writer del chained menu para HTML, el único cambio que se ha de realizar será el código javascript que irá como valor del atributo onchange del control visual.
- En la parte de presentación, se añadirá un nuevo estilo CSS para el control chained menu que indicará si se ha de usar AJAX (siempre si el dispositivo soporte dicha capacidad). Un posible nombre para este estilo será: ajax y será un valor booleano.
- La clase que se encarga de gestionar el estado del menu encadenado es ChainedMenuFlowHandler. Esta clase tiene toda la lógica de navegación del control, invocación de OAs para alimentar los submenús, calcular si un submenú sólo tiene un elemento a mostrar y así saltar automáticamente al siguiente submenu, etc. Viendo el código fuente de esta clase, se puede observar como distintas variables de contexto almacenan el identificador, optionsbind, bind, keymember y textmember de los diferentes submenús (método getValuesMenu()). Apoyándonos en estas variables se construirá convenientemente el objeto JSON que se envíe al cliente.
- Por otro lado, como será necesario enviar un código JavaScript que implemente toda la lógica en cliente, la clase que se encarga de gestionar la inclusión de ficheros JavaScript es ScriptUtil definida en el motor de presentación.
- La lógica de estado para el comportamiento del control menú encadenado sólo hará falta en el lado servidor, ya que en el lado cliente si se hace una navegación hacia atrás, cuando se produzca un evento desde una combo anterior, el servidor estará al tanto puesto que en la petición irá el identificador del submenú que la originó. De esta manera, el servidor actualizará la máquina de estados.
División de las tareas
- [TERMINADO] Cristian se encarga de realizar la implementación en el lado servidor del método sendObject y todas las acciones correspondientes que conlleve.
- José Luis trabajará en el resto de acciones. Para cualquier duda, podrá ser guiado por Cristian sobre todo en la parte del servidor.
Consideraciones
- Cuestión a tener en cuenta: está implementación sólo será tratada para PDAs.
- Tener en cuenta que la base de datos para dispositivos WURFL tiene una serie de capacidades para AJAX . No está testeado por parte de los desarrolladores de MyMobileWeb y puedo asegurar que en la versión de wurfl.xml subida en el trunk no está disponible estas capacidades.
La capacidad a tener en cuenta es ajax_xhr_type, en el wurfl_patch_2.xml para browsers de deskktop aparece con el valor standard para realizar las pruebas unitarias del desarrollo.
- Esta nueva funcionalidad se subirá al SVN en el trunk y no será necesario abrir una nueva rama.
Detenida momentaneamente la nigthly build.
- Seguir si es posible los videos de los cursos de Yahoo dados por Douglas Crawford (inventor de JSON). Son fundamentales para entender bien el lenguaje :).
- Crear un namespace en JavaScript para MyMobileWeb, mymw { ... }.
- Adjunto una prueba de concepto que hize hace mucho tiempo de JSON por si es útil para José Luis.
Ficheros JavaScript
En esta sección vamos a tratar la problemática de incluir multitud de ficheros js en una página y la compresión de los mismos.
Compresión
Solución: Comprimir los ficheros individualemente en el momento de desarrollo (al aplicar el DeployTools).
Juntando ficheros JavaScript...
- Solución 1: Todos los ficheros de la aplicación.
- Ventajas: Un único fichero, una vez cacheado no se tendrá que descargar más por parte de un cliente.
- Desventajas: Fichero muy pesado y además imposible de construir porque habría conflictos de funciones con el mismo nombre en distintos ficheros, multiidioma, etc.
- Solución 2: Actualmente se incluyen los siguiente ficheros: common.js, messages_codigoIdioma.js, mymw_ajax.js (si se necesita), presentacion_gen.js y presentacion.js. Unir estos 5 ficheros en uno llamado presentacion_codigoIdioma.js. Habrá tantos ficheros js por idioma y presentaciones de la aplicación.
- Ventajas: Una único fichero para la descarga por página.
- Desventajas: El fichero para el JavaScript customizado (presentacion.js) queda ofuscado imposibilitando su edición si así lo desea el desarrollador. Otro problema sería que el módulo mymw_ajax.js se incluye siempre y no es necesario en la mayoría de ocasiones (sólo para presentaciones con menús encadenados con estilo ajax a true). Además, como va incluido en el fichero presentacion_codigoIdioma.js, para dos presentaciones se descargará dos veces.
- Solución 3: Unir los ficheros common.js y messages_codigoIdioma.js = common_codigoIdioma.js
- Ventajas: un único fichero con lo que evitamos un link href. Siempre van juntos por lo tanto todo son ventajas y no hay incovenientes.
- Solución 4: Unir los ficheros common.js, messages_codigoIdioma.js y mymw_ajax.js = common_codigoIdioma.js
- Ventajas: un único fichero para los tres con lo que evitamos dos link href.
- Desventajas: El fichero mymw_ajax.js no siempre se debe enviar, es más, podría existir aplicaciones que las obligamos a descargarlo y no lo necesitan.
- Solución 5: La misma que la anterior pero no incluir todo el fichero mymw_ajax.js. Sólo un trozo de código el cual sabe como descargarse el resto de código del módulo de AJAX si así lo necesita la presentación.
Resoluciones
- Para la redución de los ficheros hemos usado YUI Compressor con lo que hemos disminuido cada fichero un 50% aproximadamente. Según hemos investigado, es el compresor que mejor prestaciones ofrece frente a otras opciones de software libre como JSMin ó JQuery.
- En el fichero MyMobileWeb.CodeGen.xml se ha añadido un flag para indicar si se desea comprimir los ficheros JavaScript.
<property name="Compression" value="true"/>- Estamos implementando la solución tercera para el join de ficheros y estudiando la viabilidad de las solución quinta.
