Aprendiendo Ext JS 3

¿Qué es un store y cómo funciona? Más videos

Descripción del tema

El 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.

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.

¿Olvidaste tu contraseña?

25Comentarios

  • Avatar-6 Ronhead 21/04/2009

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

    • Avatar-8 Dominic 15/01/2021

      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.

    • Avatar-5 pablo 22/04/2009

      como siempre fantástico! y cada vez se pone mas interesante

      • Avatar-6 Lord Tinchen 23/04/2009

        Muy bueno los tutoriales. Se logra entender perfectamente el tema. Te felicito!

        • Avatar-1 Osvaldo 19/07/2009

          Realmente muy buenos los tutos. sin mucho rodeo todo claro y se entiende perfectamente. te felicito!

          • Avatar-11 spit 21/07/2009

            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...

            • Avatar-7 Elías Manchón 17/08/2009

              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

              • Avatar-9 Crysfel 17/08/2009

                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

                • Avatar-3 Elías Manchón 17/08/2009

                  si, he trabajado con expresines regulares pero no con esa sintáxis.

                  • Avatar-2 cfontes 04/09/2009

                    Muy practicos, claros y sencillos los ejemplos; me han servido bastante, gracias...

                    • Avatar-6 daniel 02/10/2009

                      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

                      • Avatar-4 Merly 04/09/2010

                        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

                        • Avatar-10 Crysfel 06/09/2010

                          "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

                          • Avatar-1 Ulloa 24/10/2010

                            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,

                            • Avatar-10 Ulloa 24/10/2010

                              Crysfel, favor hacer caso omiso a esta consulta. Se debia a un error capa 8. =P

                              • Avatar-5 Michael 18/08/2011

                                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.

                                • Avatar-8 Johannsheik 23/11/2011

                                  Fantástico el tutorial, se entiende todo muy bien, pero tengo una pregunta. ¿Cómo hago para filtrar sobre lo que ya esta filtrado?

                                  • Avatar-9 Vila 08/02/2012

                                    gracias hermano del soft. siempre nos sacas de apuros...

                                    • Avatar-2 TONY 18/04/2012

                                      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

                                      • Avatar-6 DiegoVL 22/02/2013

                                        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?

                                        • Avatar-8 Crysfel 22/02/2013

                                          Eso lo miras en la documentación de la libreria, cada evento/método tiene definido ciertos parámetros que puedes utilizar. Saludos

                                          • Avatar-12 DiegoVL 22/02/2013

                                            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...

                                            • Avatar-5 Luis Hilario 07/07/2013

                                              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); } });

                                              • Avatar-1 Elias Vargas 08/04/2014

                                                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.

                                                • Avatar-9 Dominic 15/01/2021

                                                  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.

                                                  Instructor del curso

                                                  Crysfel3

                                                  Autor: Crysfel Villa

                                                  Es ingeniero de software con más de 7 años de experiencia en desarrollo web.

                                                  Descarga Código Fuente Ver Demostración

                                                  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.