Empenzando con jquery mobile

Definitivamente las aplicaciones que hagamos en los próximos años van a tener que ser usables desde dispositivos móviles y para esto hoy contamos, entre otros, con jquerymobile de la familia de jquery para aplicaciones html.

Introducción breve

  • Para agregar comportamiento a los elementos html se utiliza (principalmente) el atributo data-role lo cual define, como es de esperar por su nombre, el rol que cumplirá el elemento.
  • Si bien se pueden organizar cada pantalla como un archivo html aparte, jquerymobile ofrece el concepto de páginas, ¿y como se indica este comportamiento?... si, si, con data-role="page".
  • También contamos con otros data-role como header, content, footer, dialog, listview, button, etc.
  • Un elemento importante de definir en el <head> del html es <meta name="viewport" content="width=device-width, initial-scale=1"> el cual determina que el ancho de la página es el ancho de la pantalla de dispositivo

Nota: al momento de escribir este post, la versión 1.1 está en rc1 (Unstable build) por lo que los ejemplos están desarrollados con la última versión estable (1.0.1).



Referenciando js y css

descargar

La estructura base de cualquier página (de este post) será:

Multipage

descargar ver imagen

Podemos definir varias page en un mismo html y para acceder a cada una de ellas lo haremos con # indicando así el fragmento (o recurso secundario) que queremos cargar:


Principales partes de una página

descargar ver imagen

Cada página se divide en 3 secciones principales: header, content y footer, el atributo data-position="fixed" indica que el elemento siempre se mantendrá visible.


Navigator

descargar ver imagen

Podemos agregar un menú para navegar entre las páginas, esto se hace con el data-role="navbar", armando una lista ul/li con elementos a en su interior como la siguiente:


Listas

descargar ver imagen
Una forma bastante elegante de armar una lista es con el data-role="listview" en un elemento ul:


Mejorando las listas

descargar ver imagen
Algunos efectos interesantes sobre las lista puede ser data-filter="true" que agrega un cuadro de filtrado, data-inset="true" mejora el aspecto y data-role="list-divider" para colocar elementos (li) como divisores:


Dialogs

descargar ver imagen
Al mismo nivel que page tenemos dialog, la principal diferencia entre ambos es que el primero ocupa toda la pantalla mientras que el segundo se muestra "por sobre" la pantalla anterior y tiene cierto comportamiento propio de un dialog (como el botón para cerrarlo).

para invocar al dialog, lo mismo que antes para una page, un elemento a con href="#message"



Hasta aquí llegó este post introductorio, les dejo un ejemplo completo que también pueden descargarlo (el cual contiene los css y js necesarios para ejecutarse).

Si les pareció un framework interesante, les recomiendo seguir por el sitio de jquery-mobile que no tiene desperdicio.

Primero pasos con Knockout

Luego de varios comentarios positivos sobre este framework y de ver que ya viene incluido en asp.net mvc4, decidí darle un vistazo a knockout 2.0, como resultado de estas pruebas podría decir que knockout me parece muy útil cuando queremos hacer una aplicación web con bastante comportamiento del lado del cliente (browser), es decir, cuando queremos que el armado de la vista (html) sea responsabilidad del cliente (browser) y no tanto del servidor.

¿Que aporta knockout la programación?

Si bien para tener vistas mas dinámicas me alcanzaba con jquery, el aporte del knockout está en no tener que manipular el DOM artesanalmente sino que de eso se encarga knockout en base a los data-bind que nosotros definimos.

¿Que conceptos se agregan respecto de la simple manipulación del DOM?

Se agrega el concepto de view-model observable, uno de los pilares de knockout (sinó "el" pilar).

Ejemplo completo

Descargar

Este ejemplo utiliza mongolab y funciona simplemente abriendo el html desde el filesystem con un browser, no necesita hosting del sitio web (a los fines didáctico).


Para configurar mongolab, siga los pasos descriptos en readme.txt

Conceptos claves

  • Separar correctamente lo que corresponde a la vista de lo que corresponde al view-model
  • Utilizar los data-bind para vicular atributos de html con propiedades del view-model o para iterar como el caso de data-bind="foreach: articles"
  • Todo lo que queremos que se actualice 'automáticamente' debe ser ko.observable(...), ya sean objetos, propiedades, arrays

Analizando algunos fragmentos de código

Para inicializar todos nuestros bindings, tenemos que ejecutar ko.applyBindings luego de que se cargó nuestra página:



Para relacionar un objeto de nuestro view-model con los elementos html debemos utilizar los data-bind, por ejemplo:

donde:

  • El data-bind del form indica que cuando se haga un submit de este form, se ejecute el método add de nuestro view-model y que los data-bind internos del form trabajan con el objeto newItem de nuestro view-model
  • El data-bind del input id="new_name" está indicando que la propiedad relacionada con el value de ese input es name. ¿de quien?, si, de newItem


y por último, veamos como iterar en un array de items:


  • en primer lugar podemos ver la propiedad length bindeada al contenido del elemento span.
  • luego, podemos observar un elemento ul cuyo data-bind nos dice que va a recorrer el array articles de nuestro view-model.
  • ahora bien, dentro de cada li vamos a tener 2 elementos de tipo span que van a estar relacionados con las propiedades name y stock de la misma manera que el span anterior pero con la salvedad que estos están vinculados a cada elemento del array que estamos iterando. También tendremos 2 elementos de tipo button y, como podemos intuir del data-bind cuando se presionen invocarán a los métodos set_current y remove de nuestro view-model (y no del elemento que estamos iterando, para eso es el $parent)


Y... ¿el view-model?

Ahora veremos algunos fragmentos que considero importantes del view-model, pero pueden verlo completo bajándose el ejemplo.


Aquí podemos observar como creamos el view-model (self) creando articles como un array observable y newItem como un objeto observable. Luego definimos length como una propiedad computable.

function articulos() {
    var self = { };
    self.articles = ko.observableArray();
    self.newItem = ko.observable();

    self.length = ko.computed(function() {
        return self.articles().length;
    });


Aquí podemos observar la definición de add, el parámetro f es el form involucrado, las primeras líneas son para validarlo (jquery.validation), luego tomamos el action definido en el form asumiendo que ese es el nombre de la colección a la que queremos agregar el nuevo elemento y llamamos a hacer un $.post con self.newItem() como contenido y, de resultar exitoso el POST, se agrega la respuesta (data) a la colección de articles, previo crearla como observable.

self.add = function(f) {
    var form = $(f);

    var valid = true;
    if (form.valid !== undefined)
        valid = form.valid();

    if (valid === undefined || valid) {
        var collectionName = form.attr("action");

        rest.dopost(collectionName, self.newItem(), function(data) {
            self.articles.push(observableArticulo(data));
            self.reset_newItem();
            self.sort();
        });
    }
    return false;
};


Descargar ejemplo completo