jQuery Mobile: Modelo de navegación con Ajax

Una “page” en jQuery Mobile se compone de un elemento (generalmente un div) con un atributo data-role con el valor ‘page’, que generalmente contiene elementos div con roles de “header”, “content” y “footer”, cada una con su maquetación , formularios y widgets customizados de jQuery Mobile.
El workflow básico en la carga de páginas es como sigue:

  1. Primero, una page es pedida como una petición normal HTTP
  2. Las pages subsecuentes que sean pedidas son inyectadas en el DOM de la pagina anterior.

Por este motivo, el DOM puede tener varias pages dentro de el en un solo momento, cada una de las cuales pueden ser revisitadas cuando son enlazadas con referencia a su atributo “data-url”.

Cuando una url es pedida inicialmente, puede haber una o más pages en la response, pero solo la primera será mostrada. La ventaja de almacenar más de una page es que permite precargar páginas estáticas que son susceptibles de ser muy visitadas.

 

Navegación de páginas conducida por Ajax

Toda la nevegación con jQuery Mobile se basa sobre cambios y actualizaciones a “location.hash”. Cuando se pueda hacer, los cambios de page utilizarán una transición suave entre la page actual y la siguiente, tanto si ya esta presente en el DOM, o es automáticamente descargada via Ajax.

Los valores hash creados por jQuery Mobile son normalizados como full paths relativos a la URL de la primera página real que fue descargada.El hash siempre es mantenido como una URL valida, asi cualquier page de jQuery Mobile puede ser añadida a favoritos o referenciada desde un link. Para recuperar URL que no estan basadas en Hash, simplemente borra el # de la direccón y refresca la pagina.

En general, los cambios de hash son creados cuando quiera que un enlace es clickado en jQuery Mobile. Cuando un link es clickado, jQuery Mobile se asegurará que el link se referencia como una URL local, y asi, prevenirá el comportamiento por defecto del click de ocurrir y pedirá la url referenciada via Ajax en su vez.Cuando la página viene con exito, hará un set del location.hash a la nueva url relativa de la pagina.

 

La función $.mobile.changePage((to, transition, back, changeHash)

Dentro del framework, los cambios de página – tanto para páginas ya en el DOM como para páginas que necesitan ser descargadas via Ajax – utilizan la función $.mobile.changePage(). Esta función contiene toda la lógica para encontrar páginas hacia o desde donde se quiere transicionar , y como manejar varias condiciones de respuesta tales como page not found. Esta función puede ser invocada externamente y acepta los siguientes argumentos : ((to, transition, back, changeHash))

  • To: acepta a una string (tal como la url de un fichero o el id de un elemento local), un array (donde el primer elemento del array es cualquier pagina local desde la que transcionarias, y el segundo elemento es la pagina a la que vas) , o un objeto (con las properties url, type (‘get’ o ‘post’), y data (para parametros serializados)), el ultimo de los cuales es útil para cargar páginas que esperan datos de formulario.
  • The transition argument accepts a string representing a named transition, such as “slide”.
  • The back argument accepts a boolean representing whether the transition should go forward or in reverse.
  • Lastly, the changeHash argument accepts a boolean for whether you’d like the url to be updated upon a successful page change.

La función $.mobile.changePage() se utiliza en muchos sitios con jQuery Mobile. Por ejemplo, cuando un link es clickado, su atributo href es normalizado y entonces $.mobile.changePage() maneja el resto. También cuando los formularios son submitted, jQuery Mobile simplemente recoge unos pocos de los atributos del form, serializa sus datos y una vez mas $.mobile.changePage() es usado para manejar la submission y la respuesta.Además, los links que crean dialogos utilizan $.mobile.changePage() para abrir una page referenciada sin actualizar el hash, lo cual es útil para tener los dialogos fuera del history tracking.

Otro ingrediente clave del modelo de navegación de jQuery Mobile es el elemento ‘base’, el cual es inyectado dentro del head y modificado en cada cambio de página para asegurar que todos los recursos (css, imagenes, js,etc) referenciados en esa page serán pedidos desde un path apropiado. En los navegadores que no soportan actualizaciones dinámicas al elemento base (como Firefox 3.6), jQuery Mobile hace bucle a través de todos los recursos referenciados de la page y pone prefijos en sus href y src atributos con el base path.

Los cambios hash que ocurren independientemente de un click, tal como cuando un usuarios hace click en el boton de Atras, son manejados a través del evento hashchange, el cual es enlazado al objeto window utilizando el Ben Alman’s hashchange special event plugin (included in jQuery Mobile).Cuando ocurre un hash change (y tambien cuando la primera página se carga) , el manejador del evento hashchange envia el location.hash a la función $.mobile.changePage(), el cual de vuelta carga o recupera la pagina referenciada.

Una vez que la página referenciada esta presente en el DOM, la función $.mobile.changePage() aplica una transición entre la pagina actual activa y la nueva página. Las transiciones entre páginas ocurren a través de añadir y borrar classes que aplican animaciones CSS. Por ejemplo, en una transición hacia la izquierda, la página saliente se le dan las clases “slideleft” y “out” , y a la página entrante se le dan las clases “slideleft” e “in”, asi como una clase de “ui-page-active” para marcarla como la nueva pagin activa que esta siendo visionada. Cuando la animación esta completa, las clases “in” y “out” son eliminadas, y la pagina que ha salido pierde el class “ui-page-active”.

 

Explicación para el programador de la gestión de la base url

jQuery Mobile gestiona las peticiones http utilizando una combinación de paths URL absolutos generados y de manipular el atributo href del elemento <base>.La combinación de estas dos aproximaciones nos permite crear URLs que contienen información full path para cargar páginas, y un elemento base para hacer requests directas apropiadamente de recursos que tienen las paginas descargadas (tanto imagenes como hojas de estilo).

 

Paginas auto-generadas y urls sub-hash

Algunos plugins pueden elegir dividir dinamicamente el contenido de una pagina en varias paginas navegables, las cuales con entonces referenciadas como deep links. Por ejemplo el plugin Listview, el cual divide una UL anidada (o OL) en páginas separadas, las cuales tendrán un atributo data-url apropiado para ser enlazados como una página normal de jQuery Mobile. Sin embargo, para enlazar con estas páginas, la página que las genera debe ser primero pedida al servidor. Para hacer esto , las páginas que son auto-generadas por plugins utilizan un estructura data-url especial: <div data-url=”page.html&subpageidentifier”>

Asi, por ejemplo, una página generada con el plugin listview puede tener un atributo data-url como este:

data-url=”artists.html&ui-page=listview-1″

Cuando una página es solicitada, jQuery Mobile extrae lo que hay antes de “&ui-page” en la url para hacer una HTTP request. En el caso del ejemplo de arriba, la URL sería como esto:

http://example.com/artists.html&ui-page=listview-1 …

entonces en este caso jQuery Mobile solicitaría artists.html, despues se generan sus sub-pages, y se crea un div con el atributo data-url=”artists.html&ui-page=listview-1″ que será visualizado como la página activa.

Nota: Observese que el atributo data-url del elemento contiene una full path URL, no solo la parte después de &ui-page. Esto permite a jQuery Mobile utilizar un sencillo mecanismo consistente que hacer corresponder URLs con pages con atributos data-url.

Casos donde la navegación Ajax no será utilizada

Bajo ciertas condiciones, las peticiones http normales serán utilizadas en lugar de las peticiones Ajax. un caso donde esto es cierto es cuando se enlazan con páginas en webs externas. Asi que se puede especificar que se haga una petición normal http con los siguientes atributos:

  • rel=external
  • target (with any value, such as “_blank”)

Haciendo submits de formularios

Los submits de formularios son manejados automáticamente a través del modelo de navegación ya comentado. Para más información visita la sección de formularios.

Limitaciones conocidas

El entorno no estandar creado por el modelo de navegación de páginas de jQuery Mobile introduce algunas condiciones a tener en cuenta:

  • Cuando enlazamos a directorios, sin un nombre del fichero html en la url (por ejemplo href=”typesofcats/”  en vez de href=”typesofcats/index.html”), debemos poner la barra final. Esto es porque jQuery Mobile asume que la sección después del caracter “/” en una url es un nombre de fichero, y se borra para asi guardar una base url con la que referenciará páginas futuras.
  • Cualquier recurso referenciado unívocamente por las pages en una web de jQuery Mobile debe ser colocada dentro del elemento “page” (aquel elemento con un data-role = page). Por ejemplo, los links a estilos y scripts que son particulares de una pagina deben ser  referenciados dentro del propio div. Otra forma mejor es utilizar los eventos de pagina de jQuery Mobile para lanzar scripting especifico cuando ciertas páginas cargan.
    • Nota: cuando se descarga una pagina desde servidor que tiene un atributo data-url especificado en la maquetacion, jQuery Mobile lo utilizará para hacer un hash update. Con esto nos aseguramos que los paths de directorios resuelven con un “/” y por lo tanto serán usados en el base url path para futuras requests.
  • De la misma forma, los recursos que son utilizados de forma general en la web deben ser referenciados en la  <head> section del HTML document, o como mínimo,  fuera del elemento “page” , para prevenir que se ejecuten los mismos scripts más de una vez.
  • La palabra clave “ui-page” utilizada en referencias sub-hash urls puede ser configurada a cualquier valor, de forma que se integre dentro de tu estructura de URL. Lo puedes hacer cambiando la siguiente property jQuery.mobile.subPageUrlKey.