¿Qué es un store y cómo funciona?
Apr 21, 2009 | Español | By Crysfel | 10 Comments | Read in EnglishEl tema de hoy es fundamental ya que el objeto Store es utilizado por los componentes que necesitan comunicarse con el servidor para mostrar la información, en este tema daré un vistazo rápido a lo más importante de este componente.
Un Store es un componente que almacena temporalmente información mediante registros, es utilizado como caché. Es importante mencionar que el Store contiene a otro componente capaz de leer e interpretar la información recibida, este lector es configurado antes de solicitar la información local o al servidor.
Material de apoyo
Para este tema el material de apoyo es un HTML y un JS donde estaremos trabajando, así que es necesario descargarlo y copiarlos dentro de la carpeta “ajax” que creamos en el tema anterior la cual está dentro de la carpeta “curso” en el servidor Web que instalamos en el primer capítulo de este curso.
Encapsulando el tutorial
Antes de comenzar con el ejemplo tenemos que encapsular el código que estaremos escribiendo para evitar coaliciones.
//El namespace para este tutorial
Ext.ns('com.quizzpot.tutorial');
com.quizzpot.tutorial.Store = {
//Información dummy irá aquí
init: function(){
//esto será ejecutado cuando el DOM esté listo
//crear el store aquí
//cargar la información en el store aquí
//crear los “listeners” de los botones aquí
}
//crear el método "orderAsc" aquí
// crear el método "orderDesc" aquí
// crear el método "filter" aquí
// crear el método "query" aquí
// crear el método "count" aquí
// crear el método "find" aquí
// crear el método "log" aquí
}
//disparamos la función “init” cuando el DOM esté listo
Ext.onReady(com.quizzpot.tutorial.Store.init,com.quizzpot.tutorial.Store);
He comentado el lugar donde escribiremos el código del tutorial, con la intención de que tengas una idea global de la estructura final del código.
La información
Para este ejemplo vamos a tomar la información de un arreglo, es importante mencionar que debemos crear un arreglo bidimensional el cual será “procesado” por el store que crearemos más adelante, este arregló estará al inicio del objeto “com.quizzpot.tutorial.Store” de la siguiente manera:
data: [ //información dummy para el ejemplo [1,'Crysfel','Software developer','m',25], [2,'Sasha','Figure skater','f',23], [3,'Jack','Software Architect','m',35], [4,'John','Javascript developer','m',24], [5,'Sara','Tester','f',31] ],
La información está contenida en un arreglo el cual contiene otros arreglos con la información, cada arreglo interno será un registro donde la posición cero es el “identificador” del registro, la posición uno es el “nombre” de una persona, la posición dos la “ocupación”, la posición tres es el “género” de la persona y la posición número cinco es la “edad”.
Crear un Store con información local
Ahora vamos a crear un “SimpleStore” con el que estaremos trabajando en este tutorial, esto lo hacemos de la siguiente manera:
//creamos una instancia del SimpleStore
this.store = new Ext.data.SimpleStore({
fields: [ //definimos los campos que tendrá...
{name:'name',mapping:1}, //cada registro...
{name:'occupation',mapping:2}, // y lo relacionamos...
{name:'gender',mapping:3},// con una posición en el...
{name:'age',mapping:4}//arreglo que tiene la información
],
id: 0 //definimos la posición del ID de cada registro
});
Hasta este punto hemos creado el store, aún no tiene información pero ya es capaz de leer el arreglo que definimos anteriormente, la propiedad “fields”, que esta en la configuración del store, es donde se define el nombre de las propiedades de los registros mediante la propiedad “name” y se relaciona al arreglo con la información mediante la propiedad “mapping”, en este caso la propiedad mapping se le asigna la posición en el arreglo de donde sacará su contenido.
Cargar la información en el Store
Introducir la información en el Store es muy fácil ya que estamos usando información local contenida en un arreglo. Para que el store pueda consumir el arreglo definido lo hacemos de la siguiente manera:
//cargar la información del arreglo this.store.loadData(this.data);
Si todo ha salido bien ya podremos usar la información contenida en el store.
Crear los “listeners” de los botones
Lo siguiente que haremos es crear los “listeners” del evento clic de cada botón que hay en el documento html.
Ext.fly('personBtn').on('click',this.find,this);
Ext.fly('txt').on('keyup',function(event,cmd){
if(event.getKey() === event.ENTER){ //cuando sea la tecla ENTER
this.find(); // realizamos la búsqueda
}
},this);
Ext.fly('ascBtn').on('click',this.orderAsc,this);
Ext.fly('descBtn').on('click',this.orderDesc,this);
Ext.fly('older2030Btn').on('click',this.query,this);
Ext.fly('older30Btn').on('click',this.filter,this);
Ext.fly('countBtn').on('click',this.count,this);
El código anterior ya es familiar para nosotros, de no ser así te recomiendo darle un repaso a los temas anteriores donde se habló al respecto, lo más importante a resaltar es que las funciones que se han asignado a cada evento no las hemos definido.
Ordenar los registros
Ordenar la información es muy importante, y podemos hacerlo de una manera muy sencilla utilizando el método “sort”.
, //nota la coma separadora XD
orderAsc: function(){
this.store.sort('name','ASC'); // ordenar en forma ascendente
this.store.each(function(record){//por cada registro...
this.log(record.get('name')); //imprime la propiedad “nombre”
},this);
this.log('___________________________________');
}, // <--- esta coma es importante
orderDesc: function(){
this.store.sort('name','DESC'); //Ordenar en forma descendente
this.store.each(function(record){ // por cada registro...
this.log(record.get('name')); //imprime la propiedad “nombre”
},this);
this.log('___________________________________');
}
El método “sort” recibe como primer parámetro la propiedad por la que serán ordenados los registros y como segundo parámetro el tipo de orden, ascendente o descendente; una vez que se han ordenado se pueden recorrer los registros utilizando el método “each” del store, el cual itera sobre los registros.
El método “log” no ha sido definido aún, lo haremos más adelante, por ahora puedes poner un “console.debug” para imprimir en la consola de Firebug.
Filtrar registros en el store
En ocasiones es necesario filtrar la información contenida en el Store dependiendo algún criterio dado, en este ejemplo voy a realizar un filtro de las personas cuya edad sea mayor de 30 años; esto lo haré utilizando el método “filterBy”.
, // <--- La coma separadora
filter: function(){
//filtrar a las personas...
this.store.filterBy(function(record,id){
return record.get('age') >= 30; //mayores a 30 años
});
//por cada registro...
this.store.each(function(record){
//imprimir en el “log”
this.log(record.get('name')+' is older than 30 '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age'));
},this);
//limpiar los filtros
this.store.clearFilter();
this.log('___________________________________');
}
El método “filterBy” acepta como primer parámetro una función que será ejecutada por cada registro del store, ahí es donde se ha definido la condición deseada (edad mayor a 30 años), cuando la función retorne “true” el registro será tomado en cuenta y cuando retorne “false” el registro será descartado.
Luego de aplicar el filtro al store se ejecuta la función “each”, es importante mencionar que la función “each” únicamente será ejecutada sobre los registros que han sido filtrados anteriormente ya que se le ha aplicado un filtro al store.
Por último mediante la función “clearFilter” se limpian los filtros aplicados al store, permitiendo que todos los registros puedan ser utilizados nuevamente.
Buscar registros
El método anterior nos proporciona un manera de buscar registros descartando los registros que no necesitamos, el método “queryBy” hace algo semejante pero la diferencia es que regresa los registros encontrados en una colección, esto nos puede ser más útil o quizás más claro que el método anterior.
,//<--- La coma separadora
query: function(){
//buscar gente mayor a 20 y menor que 30 años
var collection = this.store.queryBy(function(record,id){
return record.get('age') >20 && record.get('age')<30;
});
//por cada item en la colección
collection.each(function(item,index){
//imprime su nombre y edad
this.log(item.get('name')+' is '+item.get('age')+ ' and '+(item.get('gender')=='f'?'she':'he')+' is younger than 30');
},this);
this.log('___________________________________');
}
Como puedes notar es muy semejante (por no decir igual) que el método anterior, la única diferencia es que regresa una colección con los registros que cumplen la condición especificada.
Buscar por una propiedad
Si queremos buscar un registro único podemos utilizar el método “find” el cual recibe como primer parámetro la propiedad sobre la cual queremos realizar la búsqueda, como segundo parámetro recibe un “String” o una expresión regular con el criterio de búsqueda, el tercer parámetro es opcional y es el número de registro donde comenzará a realizar la búsqueda, en el cuarto parámetro que también es opcional definimos si la búsqueda será ejecutada en cualquier parte del texto y el quinto parámetro define si queremos que ignore las mayúsculas y minúsculas.
//propiedad: name
//value: Crys
//comienza en: 0
//sobre cualquier parte del valor del registro
//no toma en cuenta mayúsculas y minúsculas
this.store.find('name', 'Crys',0,true,false);
Lo que regresa el método “find” es el índice donde encuentra la primera coincidencia, en caso de no encontrar nada regresará un “-1”.
,
find: function(){
//tomamos lo que se introdujo en la caja de texto
var value = Ext.fly('txt').getValue();
//si no hay nada salimos de esta función
if(Ext.isEmpty(value)) return;
//realizamos la búsqueda sobre la propiedad “name”
var index = this.store.find('name',value,0,true,false);
//si en encontró algo
if(index>=0){
//tomamos el registro por medio del índice...
var record = this.store.getAt(index);
//e imprimimos la información encontrada
this.log(record.get('name')+' work as a '+record.get('occupation')+' and '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age')+' years old');
}else{
//si nada fue encontrado se le avisa al usuario
this.log('<strong>'+value+' not found!</strong>');
}
}
Puedes ver que se ha utilizado el método “getAt” para tomar el registro completo dándole el índice que necesitamos.
Si sabemos el ID del registro podemos sacarlo inmediatamente utilizando el método “getById”, lo que vamos a hacer es verificar si el usuario introdujo un número en la caja de texto, de ser así utilizaremos el ID, si es texto entonces ejecutaremos el código anterior.
, //<---
find: function(){
//tomamos lo que se introdujo en la caja de texto
var value = Ext.fly('txt').getValue();
//si no hay nada salimos de esta función
if(Ext.isEmpty(value)) return;
//si el valor es númerico
if(/^\d+$/.test(value)){
//buscamos por ID
var record = this.store.getById(value);
if(!Ext.isEmpty(record)){
//si se encontró algo se imprime
this.log(record.get('name')+' work as a '+record.get('occupation')+' and '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age')+' years old');
}else{
//si nada fue encontrado se avisa al usuario
this.log('<strong>Record with id: '+value+' was not found!</strong>');
}
}else{
//realizamos la búsqueda sobre la propiedad “name”
var index = this.store.find('name',value,0,true,false);
//si en encontró algo
if(index>=0){
//tomamos el registro por medio del índice...
var record = this.store.getAt(index);
//e imprimimos la información encontrada
this.log(record.get('name')+' work as a '+record.get('occupation')+' and '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age')+' years old');
}else{
//si nada fue encontrado se le avisa al usuario
this.log('<strong>'+value+' not found!</strong>');
}
}
}
El código anterior decide si la búsqueda será realidad por ID o por la propiedad especificada (en este caso “name”).
Contar los registros del store
Para contar los registros que actualmente están en el store es muy fácil, únicamente utilizamos el método “getCount”.
,
count: function(){
//imprime el total de registros
this.log('<strong>Total records: '+this.store.getCount()+'</strong>');
}
Notar que este método solo regresa los registros que actualmente están en el store.
El Log
Por último vamos a definir el método “log” que hemos estado usando para desplegar los mensajes.
,
log: function(txt){
var el = Ext.get('response'); // get the LOG
el.select('p.newest').removeClass('newest'); // quitar la última actualización
Ext.DomHelper.append(el,'<p class="newest">'+txt+'</p>'); //actualizar el log
el.scrollTo('top',el.dom.scrollHeight); //scroll abajo
el.select('p.newest').highlight('F5FC49',{duration:0.5}); //resaltar el ultimo mensaje
}
Lo que hicimos en el código anterior es tomar el nodo “response” y agregarle párrafos con el texto que recibe, luego hacemos que destelle en color amarillo.
Conclusiones
Es importante que sepamos como buscar información contenida en un store, ya que este componente es muy usado para manipular información, es fundamental conocerlo para una mejor comprensión del Framework.
En este tema vimos un store muy sencillo que toma la información de un arreglo definido con JavaScript, en el mundo real la información viene de una base de datos, de una servicio Web o de algún otro lugar, en los siguientes temas veremos como realizar esto.
Si tienes alguna duda o pregunta déjalas en los comentarios con gusto las responderé y recuerda seguirnos en Twitter para estar al tanto de las actualizaciones o bien inscribirte a las Feeds.







Estan muy buenos los tutos a veces me sacan de apuros y otras aprendo nuevas cosas que hacer
gracias
quizzzzzzzpot