Tu primera app con Sencha Touch

Manejando eventos personalizados Más videos

Descripción del tema

Ya casi tenemos completo nuestro grid, solo falta agregar eventos a las columnas para que podamos ordenar la información, la idea es que podamos ordenar los resultados de manera ascendente o descendente cuando el usuario presione alguna de las cabeceras de las columnas.

Lo primero que vamos a hacer es modificar el template del header que usamos para el grid, agregaremos el índice de cada columna, esto para que podamos recuperar la columna que tenemos en memoria y saber el dataIndex.

Ext.define('Bleext.view.grid.Grid', {
    extend: 'Ext.Container',
    
    //...

    config: {
        layout      : 'fit',
        columns     : null,
        store       : null,
        tplColumns  : [
            '<tpl for="columns">',
                '<tpl if="width">',
                //adding the data-index
                '<div data-index="{[xindex - 1]}" class="bleext-column-header" style="width:{width}px;">{text}</div>',
                '<tpl else>',
                //adding the data-index
                '<div data-index="{[xindex - 1]}" class="bleext-column-header" style="flex:{flex}">{text}</div>',
                '</tpl>',
            '</tpl>'
        ].join('')
    },

    initialize  : function(){
        //...
    },

    //...
});

Con ese cambio podremos saber sobre cuál columna el usuario dio tap y tomando ese índice podremos sacar la configuración de la columna en el arreglo de columnas que definimos anteriormente. Recordamos que xindex es el índice en cada iteración del for, es una variable que se crea automáticamente, le restamos 1 porque necesitamos iniciar en la posición cero y xindex inicia en la posición 1.

Una vez que tenemos los indices en el template vamos a agregar un listener al evento tab del componente principal.

Ext.define('Bleext.view.grid.Grid', {
    extend: 'Ext.Container',
    
    //...

    initialize  : function(){
        var me = this;

        me.add(me.buildColumns());
        me.add(me.buildDataview());

        me.callParent(arguments);

        me.element.on('tap',me.handleCustomEvents,me); //Step 1
    },

    handleCustomEvents  : function(event){ //Step 2
       //code here
    }
});
  1. En el primer paso agregamos el listener a la propiedad element, este elemento contiene una instancia de la clase Ext.dom.Element la cual tiene una referencia al div (nodo) principal del componente en el DOM, a este nodo es al que ponemos el listener, esto significa que la función handleCustomEvents se ejecutará donde quiera que el usuario presione (dentro de este componente).
  2. En el segundo paso simplemente definimos la función que escuchar al evento tap, esta función será ejecutada cada que el usuario haga tap sobre el grid, de esta manera podríamos escuchar eventos no solamente de las columnas.

El método on, recibe tres parámetros, el primero es el evento que queremos escuchar, en este caso el tap, pero podríamos escuchar cualquier otro disponible. El segundo parámetro es la función a ejecutar y el tercer parámetro es el scope en el que se ejecutará la función, en este caso queremos que la función se ejecute sobre esta misma clase, por eso es que le pasamos la variable me.

Lo siguiente es disparar el evento que nos permitirá en nuestra aplicación invocar el servicio de itunes y solicitar los resultados ordenados por la columna que se presiono.

handleCustomEvents  : function(event){
    var me  = this,
        //Step 1
        dom = event.getTarget('.bleext-grid-header-container .bleext-column-header'),
        column,
        index;

    if(dom){
        index = Ext.fly(dom).getAttribute('data-index'); //Step 2
        
        column = me.getColumns()[index];
        column.direction = column.direction === 'ASC'?'DESC':'ASC'; //Step 3
        
        this.fireEvent('sort',column.dataIndex,column.direction,column); //Step 4
    }
}
  1. En el paso uno verificamos si el nodo sobre el que el usuario dio tap fue una columna, para eso usamos un selector de CSS, si ese selector coincide con el nodo que se dio tap entonces el método getTarget regresará el nodo de la columna, de lo contrario regresará null y significa que se dio tap en algún otro lado pero no en alguna columna.
  2. El paso dos se ejecutará únicamente si el usuario de tap sobre una columna, aquí tomamos el atributo data-index para sacar el indice que corresponde la columna, usamos el método Ext.fly para manipular el nodo fácilmente.
  3. En el paso tres verificamos la propiedad direction, y le asignamos la dirección hacia donde vamos a ordenar, ascendente o descendente, la variable column contiene la configuración de la columna que se selecciono.
  4. Por último, en el paso cuatro disparamos un evento, el método fireEvent al menos espera el primer parámetro que indica el nombre del evento a disparar, luego podemos todos los parámetros que necesitemos enviar a todos aquellos componentes que estén escuchando este evento, en este caso mandamos los datos de la columna que se va a ordenar.

Como se puede observar no estamos ordenando aquí, podríamos hacerlo de ser requerido, simplemente invocando el método sort del store. Pero para este ejemplo vamos a ordenar en el servidor, pasándole el campo y la dirección a ordenar cuando hagamos la llamada al API de itunes. Eso lo haremos más adelante cuando definamos nuestros controllers.

Si en este momento probamos nuestro código no vamos a ver ningún cambio, ya que solamente estamos disparando un evento pero nadie está escuchando. Para hacer una pequeña prueba vamos a mostrar un alerta con la información recibida. En la clase Results (app/view/Results.js) agregamos el siguiente código.

Ext.define('Itunes.view.Results', {
    extend  : 'Bleext.view.grid.Grid',
    xtype   : 'results',
    requires: [
        
    ],

    config: {
        columns : [
            //...
        ],
        store   : {
            //...
        },
        listeners : { //Step 1
            sort : function(dataIndex,direction,column){ //Step 2
                //Step 3
                Ext.Msg.alert('Sort','DataIndex: '+dataIndex+' Direction: '+direction);
            }
        }
    }
});
  1. En el paso uno usamos la propiedad listeners, esta propiedad nos permite definir un objeto con todos los listeners que necesitemos agregar a este componente, ya que estamos extendiendo de la clase Grid, podemos agregar listeners a todos los eventos definidos en esa clase.
  2. En el paso dos definimos el evento sort, este evento fue declarado en la super clase, es por eso que lo podemos usar, ademas la función esta recogiendo todos los parámetros que fueron enviados a la hora de hacer el fireEvent.
  3. En el tercer paso simplemente mostramos un alerta con los parámetros recibidos.

Si probamos nuestra app en un navegador webkit, en el simulador de iOS o inclusive en el navegador de nuestro iPad o tablet veremos una algo como la siguiente imagen.

Sort in Secha Touch

Ordenar el grid

EL grid esta disparando el evento del sort para cada columna, con esto ya podremos realizar la petición al API de itunes indicándole como queremos order la información.

Por último vamos a propagar los eventos del dataview a la clase grid, esto para que en lugar de escuchar al dataview escuchemos directamente sobre la clase grid.

Ext.define('Bleext.view.grid.Grid', {
    extend: 'Ext.Container',

    //..

    initialize  : function(){
        var me = this,
            dataview;

        me.add(me.buildColumns());
        dataview = me.add(me.buildDataview()); //Step 1

        me.callParent(arguments);

        me.element.on('tap',me.handleCustomEvents,me);

        //step 2
        me.relayEvents(dataview,[
            'itemtap','itemdoubletap','itemsingletap','itemswipe','itemtaphold',
            'itemtouchend','itemtouchmove','itemtouchstart','select','refresh'
        ]);
    },

    //..
});
  1. En el paso uno tomamos la instancia del dataview, el método add siempre regresa el objeto que se ha agregado al contenedor, en este caso el dataview.
  2. En el paso dos utilizamos el método relayEvents, este método básicamente nos permite copiar los eventos de un componente a otro, no es que los copie como tal pero si va a dispararlos como si fueran de el mismo, en este caso necesitamos que los eventos del dataview se disparen desde el grid.

El primero parámetro del método relayEvents es el componente del que vamos a copiarle sus eventos, el segundo parámetro es un arreglo con todos los eventos que queremos disparar desde el grid.

Experimenta

Intenta poner un listener al evento itemdoubletap, puedes desplegar un alerta o simplemente desplegar un mensaje en la consola, revisa la documentación de los parámetros que envía cada evento. Sígue probando el resto de los eventos disponibles.

Si has venido siguiente el curso, sabras que estamos usando git, es hora de guardar nuestro cambios en el historial.

$ git add .
$ git commit -m 'Adding the listeners to the columns'

En el siguiente tema comenzaremos a estilizar nuestra app, la verdad es que a este punto se ve muy fea y el grid no parece grid, asegurate de tener instalado Compass para poder compilar el CSS de manera correcta.

Si te ha gustado este tutorial agradecería en gran manera pudieras compartirlo en las redes sociales, me ayudarías mucho de esa manera.

Te gustaría recibir más tutoriales como este en tu correo?

Este tutorial pertenece al curso Tu primera app con Sencha Touch, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.

Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!

Si no gustas registrarte en este momento no es necesario! Aún así puedes recibir los nuevos tutoriales en tu correo! Jamás te enviaremos Spam y puedes cancelar tu suscripción en cualquier momento.

¿Olvidaste tu contraseña?

Se el primero en comentar!

Instructor del curso

Crysfel3

Autor: Crysfel Villa

He desarrollado varias aplicaciones con Sencha Touch, algunas las puedes encontrar en el App Store de apple.

Descarga Código Fuente Ver Demostración

Regístrate a este curso

Este tutorial pertenece al curso Tu primera app con Sencha Touch, revisa todos los tutoriales que tenemos en este mismo curso ya que están en secuencia y van de lo más sencillo a lo más complicado.

Ya que este curso no está finalizado al registrarte podrás recibir en tu correo los nuevos tutoriales de este curso!

Tendrás acceso a descargar los videos, códigos y material adicional.

Podrás resolver los ejercicios incluidos en el curso así como los Quizzes.

Llevarás un registro de tu avance.