¿Qué es un store y cómo funciona? Más videos
Descripción del tema
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.Te gustaría recibir más tutoriales como este en tu correo?
Este tutorial pertenece al curso Aprendiendo Ext JS 3, 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.
Regístrate a este curso
Este tutorial pertenece al curso Aprendiendo Ext JS 3, 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.
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.
25Comentarios
Estan muy buenos los tutos a veces me sacan de apuros y otras aprendo nuevas cosas que hacer gracias quizzzzzzzpot
Tengo una duda familia, aca se las dejo necesito su ayuda. Tengo un CRUD , donde se me hace necesario mantener en el justo momento en que recargo el store del grid, la fila seleccionada he buscado y hasta ahora los casos encontrados no me han funcionado Espero por su ayuda, tengo buenas referencias de ustedes aca.
como siempre fantástico! y cada vez se pone mas interesante
Muy bueno los tutoriales. Se logra entender perfectamente el tema. Te felicito!
Realmente muy buenos los tutos. sin mucho rodeo todo claro y se entiende perfectamente. te felicito!
En este tema se hecha de menos un videotuto... porque aqui ya hay conceptos algo mas liosos para comprender para alguien como yo que solo he programado en c++ en la universidad,de todas formas esta basntante bien y mas o menos se comprende todo...
Lo que me ha dejado descolocado ha sido la sentencia en javascript para testear el tipo de dato de la variable value, en concreto la línea que hace referencia a la siguiente expresión: if(/^\d+$/.test(value)) Es la primera vez que veo eso. Salu2
Son expresiones regulares (RegExp) digamos que es un "mini" lenguaje que la mayoría de los lenguajes implementan (JAVA, PHP, Ruby, Javascript,etc...), es muy poderoso y te resuelve muchos problemas ;) saludos
si, he trabajado con expresines regulares pero no con esa sintáxis.
Muy practicos, claros y sencillos los ejemplos; me han servido bastante, gracias...
Hola Crysfel muy bueno tu pagina pero necesito saber, bueno si es que puedes, lo que pasa es que necesito llenar un textfield desde un datastore, el campo que necesito trae el mismo dato en todas las tuplas, no se si me explique bien Saludos ADIOS
Bueno, primero agradecerte por el curso esta interesante y me está ayudando bastante. Tengo una duda en esta parte es referente a la clase q empleas en el LOG - "newest" me podrías explicar un poquito más por favor. GRACIAS
"newest" es una clase CSS que se le agrega al último parrafo que se ha insertado al DOM, servirá para saber cuales nodos se animarán. Saludos
Hola Crysfel, este sitio esta excelente. En este tema y el anterior he descargado los archivos pero al abrirlos no hacen nada. Es necesario escribir algun codigo, no veo donde indiques eso. Saludos,
Crysfel, favor hacer caso omiso a esta consulta. Se debia a un error capa 8. =P
Hola, tengo un problema al intentar realizar un filtro con un JsonStore, según la documentación tambien cuenta con este metodo, pero cuando lo llamo no hace ningun en el grid.
Fantástico el tutorial, se entiende todo muy bien, pero tengo una pregunta. ¿Cómo hago para filtrar sobre lo que ya esta filtrado?
gracias hermano del soft. siempre nos sacas de apuros...
necesito un ejemplo para actualizar el contenido de un grid que esta en una base de datos automaticamente al darle click al un boton gracias
Hola tengo una duda de principiante,he visto en varios ejemplos que dentro de la funcion colocan parametros, como se sabe cuales son los parametros para usarlos posteriormente? por ejemplo: ..filterBy(function(record,id)... Porque son dos parametros y porque esos nombres?
Eso lo miras en la documentación de la libreria, cada evento/método tiene definido ciertos parámetros que puedes utilizar. Saludos
Caramba, ya lo encontre en el apartado metodos de ext.data.store, discuplas que estoy aprendiendo... Por otro lado, de casualidad sabes donde encuentro el ejemplo de este link actualizado a extjs 4, http://www.sencha.com/learn/building-a-grid-with-a-livesearch-form/ es lo que quiero hacer (PHP-MySql-Grid-JSON), gracias! PD: seria genial si tienes algun tutorial similiar...
hola Crysfel, muy bueno y claro la explicacion, pero tengo un detalle tengo una grilla con 4 campos uno de ellos es el precio, debajo de la grilla una caja de texto que sirve para digitar el precio. Como hago para que me grabe solo ese precio en el registro seleccionado¡? lo estuve haciendo asi y no me funciona grid1.store.each(function(r,id){ if (r.get('id_cer1') == index2){ r.set('precio',wprecio); r.set('total',wtotal); r.commit(); console.log(r); } });
Estimados nececito ayuda, tengo una aplicacion con extjs que funciona muy bien en chrome, pero al momento de abrirla en firefox no se "dibujan" los componentes, solo muestra las palabras o letras, pero no grillas, botones, fields, etc. Necesito ayuda porfavor! gracias.
Tengo una duda familia, aca se las dejo necesito su ayuda. Tengo un CRUD , donde se me hace necesario mantener en el justo momento en que recargo el store del grid, la fila seleccionada he buscado y hasta ahora los casos encontrados no me han funcionado Espero por su ayuda, tengo buenas referencias de ustedes aca.