Aprendiendo Ext JS 3

Leer información de un XML Más videos

Descripción del tema

El día de hoy veremos como leer el contenido de un XML mediante un “reader” y lograr manipular la información mediante un Store, vamos a utilizar Ajax para cargar la información dentro del Store y trabajar con ella más adelante.

Material de apoyo

Para continuar es necesario descargar el material de apoyo, descomprimir y copiar los tres archivos que contiene el zip a la carpeta “ajax” (la misma del tutorial anterior) que se encuentra en el servidor Web que instalamos en el primer capitulo del curso. Para este tema vamos a utilizar el mismo código que escribimos en el tutorial anterior, esto quiere decir que haremos (visual y funcionalmente) lo mismo que en el tutorial anterior, la diferencia es que vamos a cambiar el Store para que pueda cargar la información mediante una llamada Ajax al servidor el cual regresará el contenido en formato XML. No voy a explicar el código que viene en el material de apoyo pues ya lo hice el día de ayer, si tienes dudas sobre su funcionamiento te recomiendo repasar lo explicado anteriormente.

Estructura general

Vamos a editar el archivo “xml.js” veremos algo semejante a esto:
//the namespace for this tutorial
Ext.ns('com.quizzpot.tutorial');

com.quizzpot.tutorial.Store = {
	init: function(){
		
		//we will write code only between the asterisks
		//*************************************************************//
		//code here the record
		
		//code here the xml reader
		
		//code here the proxy
		
		//code here the Store
		
		//load the data with an Ajax call
		
		//*************************************************************//	
		//the next code is the same as the last tutorial
		//listeners for the buttons
		Ext.fly('personBtn').on('click',this.find,this);
		Ext.fly('txt').on('keyup',function(event,cmd){
			if(event.getKey() === event.ENTER){ //when press ENTER
				this.find(); // perform the search
			}
		},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);
		
	},
	
	orderAsc: function(){
		this.store.sort('name','ASC'); // sort the store ASC
		this.store.each(function(record){
			this.log(record.get('name')); //print each name
		},this);
		this.log('___________________________________');
	},
	
	orderDesc: function(){
		this.store.sort('name','DESC'); //sort the store DESC
		this.store.each(function(record){
			this.log(record.get('name')); //print each name
		},this);
		this.log('___________________________________');
	},
	
	filter: function(){
		//filter people...
		this.store.filterBy(function(record,id){
			return record.get('age') >= 30; //older than 30 years old
		});
		
		this.store.each(function(record){
			//print on screen
			this.log(record.get('name')+' is older than 30 '+(record.get('gender')=='f'?'she':'he')+' is '+record.get('age'));
		},this);
		//clear the filters
		this.store.clearFilter();
		this.log('___________________________________');
	},
	
	query: function(){
		//query the store, search for people older than 20 and younger than 30
		var collection = this.store.queryBy(function(record,id){
			return record.get('age') >20 && record.get('age')<30;
		});
		
		//for each item found...
		collection.each(function(item,index){
			//print the info on the screen
			this.log(item.get('name')+' is '+item.get('age')+ ' and '+(item.get('gender')=='f'?'she':'he')+' is younger than 30');
		},this);
		this.log('___________________________________');
	},
	
	count: function(){
		//count the records in the store
		this.log('<strong>Total records: '+this.store.getCount()+'</strong>');
	},
	
	find: function(){
		var value = Ext.fly('txt').getValue();
		if(Ext.isEmpty(value)) return;
		//if the value is a number
		if(/^\d+$/.test(value)){
			//find by ID
			var record = this.store.getById(value);
			if(!Ext.isEmpty(record)){
				//if found, log it
				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{
				//alert the user if nothing is found
				this.log('<strong>Record with id: '+value+' was not found!</strong>');
			}
		}else{
			//if it is text, search the name property
			var index = this.store.find('name',value,0,true,false);
			//if something is found...
			if(index>=0){
				//get the record by the index...
				var record = this.store.getAt(index);
				//and print the information
				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{
				//alert the user if nothing is found
				this.log('<strong>'+value+' not found!</strong>');
			}
		}
	},
	
	log: function(txt){
		var el = Ext.get('response'); // get the LOG
		el.select('p.newest').removeClass('newest'); // remove last update
		Ext.DomHelper.append(el,'<p class="newest">'+txt+'</p>'); //update the log
		el.scrollTo('top',el.dom.scrollHeight); //scroll down
		el.select('p.newest').highlight('F5FC49',{duration:0.5}); //highlight the last message
	}
}

Ext.onReady(com.quizzpot.tutorial.Store.init,com.quizzpot.tutorial.Store);
El código anterior está debidamente empaquetado, y cuenta con métodos donde se invoca al store, el cual no hemos definido aún, por lo tanto si en este momento das clic sobre cualquier botón en el HTML aparecerá un error. Para este tutorial vamos a escribir el código solo entre los asteriscos que se encuentran al inicio, he puesto comentarios de lo que vamos a ir realizando paso a paso.

El XML a utilizar

Ext JS nos proporciona una manera muy fácil de manipular la información contenida en un XML, no tenemos que movernos por el árbol generado para acceder a las propiedades y atributos ni recorrer los nodos mediante ciclos, esto es una gran ventaja pues nos ahorra mucho tiempo en el desarrollo. El XML que vamos a utilizar para este tutorial esta contenido en el archivo “data.php” donde únicamente se están modificando las cabeceras para la respuesta e imprimiendo la información en XML, en el mundo real la información saldría de una base de datos, de un servicio Web o de alguna otra fuente, por cuestiones de aprendizaje lo he dejado así de simple:
<?php
	header("Content-Type: text/xml"); 
	
	echo '<?xml version="1.0" encoding="UTF-8"?>';
?>

<dataset>
	<results>9</results>
	<person active="true">
		<id>1</id>
		<name>Crysfel</name>
		<occupation>Software developer</occupation>
		<gender>m</gender>
		<age>25</age>
	</person>
	<person active="false">
		<id>2</id>
		<name>Sasha</name>
		<occupation>Figure skater</occupation>
		<gender>f</gender>
		<age>24</age>
	</person>
	<person active="true">
		<id>3</id>
		<name>Jack</name>
		<occupation>Software Architect</occupation>
		<gender>m</gender>
		<age>35</age>
	</person>
	<person active="true">
		<id>4</id>
		<name>John</name>
		<occupation>JavaScript developer</occupation>
		<gender>f</gender>
		<age>24</age>
	</person>
	<person active="true">
		<id>5</id>
		<name>Sara</name>
		<occupation>Designer</occupation>
		<gender>f</gender>
		<age>31</age>
	</person>
	<person active="true">
		<id>6</id>
		<name>Nicole</name>
		<occupation>Tester</occupation>
		<gender>f</gender>
		<age>28</age>
	</person>
	<person active="false">
		<id>7</id>
		<name>Carl</name>
		<occupation>Photographer</occupation>
		<gender>m</gender>
		<age>45</age>
	</person>
	<person active="true">
		<id>8</id>
		<name>Will</name>
		<occupation>Actor</occupation>
		<gender>m</gender>
		<age>32</age>
	</person>
	<person active="false">
		<id>9</id>
		<name>Penny</name>
		<occupation>Waitress</occupation>
		<gender>f</gender>
		<age>29</age>
	</person>
</dataset>
A continuación se explican los pasos que son necesarios para poder manipular la información contenida en el XML.

Paso 1: Crear el registro Person

Lo primero que debemos hacer es definir los campos que tendrán los registros, además necesitamos indicarle a cada registro de donde proviene el contenido que tendrá.
//create the "Person" record
var Person = Ext.data.Record.create([
	{name: 'active', mapping:'@active', type:'boolean'}, // mapping an attribute and setting a type for this field
	{name: 'name', mapping: 'name'},// "mapping" property not needed if it's the same as "name"
	{name: 'occupation'}, // This field will use "occupation" as the mapping.
	{name: 'age', type:'float'}, // this field will use "age" as the mapping and its a float type
	{name: 'gender'}
]);
Para crear un registro se utiliza el método “create” del objeto “Ext.data.Record”, el cual recibe un arreglo con los campos que contendrá, mediante la propiedad “name” se le indica el nombre que se le dará al campo, también se le puede especificar el tipo de dato que será (boolean, date, float, etc...) y de ser necesario utilizar la propiedad “mapping” para hacer la relación con la información en el XML. Algo que quiero resaltar es que la propiedad “active” tiene un “mapping” el cual ha sido relacionado con un atributo que está en el nodo “person” del XML, hay que notar que para indicar que es un atributo y no un nodo es necesario anteponer una arroba (@).

Paso 2: Crear el “reader” para XML

Una vez que definimos las propiedades del registro necesitamos crear el “reader” que se encargará de manipular el XML.
//creates the reader for the XML data
var reader = new Ext.data.XmlReader({
   totalRecords: "results", // The element which contains the total dataset size (optional)
   record: "person",        // The repeated element which contains row information
   id: "id"                 // The element within the row that provides an ID for the record (optional)
}, Person);
El constructor del “XmlReader” recibe como primer parámetro un objeto de configuración en el cual se define el nodo donde se encuentra el total de registros mediante la propiedad “totalRecords”, ese nodo debe estar en el XML; se define también el “id” que será utilizado para los registros y lo más importante, la propiedad “record” que es el nodo del XML de donde toma la información para llenar los registros, es importante mencionar que en esta propiedad es donde en el paso uno de este tutorial, se definieron las propiedades de los registros. Como segundo parámetro recibe el registro que será utilizado y llenado con la información.

Paso 3: Crear el Proxy

Si queremos que mediante llamadas Ajax se cargue la información dentro del store tenemos que definir el lugar de donde se solicitará la información y opcionalmente el método HTTP usado para realizar la llamada Ajax (GET o POST).
//creates the proxy
var proxy = new Ext.data.HttpProxy({
	method:'POST', //configure the http method GET or POST
	url: 'data.php' //the URL for the Ajax call
});
El código anterior define el método usado y la URL que será invocada.

Paso 4: Crear el Store

Después de definir el “reader” y el “proxy” podemos crear el store de la siguiente manera:
//creates the Ext.data.Store
this.store = new Ext.data.Store({
	proxy: proxy, //setting the proxy
	reader: reader //setting the reader
});
Con eso es suficiente por ahora, es necesario aclarar que el Store acepta diferentes implementaciones de “readers”, por ejemplo el JsonReader o en este caso XmlReader.

Paso 5: Cargar la información en el Store

Por último vamos a solicitar mediante Ajax la información al servidor de la siguiente manera:
//loading the data
this.store.load({params:{param1:'value'}});
El método “load” realiza la petición al servidor utilizando Ajax, opcionalmente podemos pasarle los parámetros que necesitemos mediante un objeto que contenga la propiedad “params”, esto es muy útil si la información que solicitamos es variante, por ejemplo aquí podría enviarle al servidor el “id” de una persona para que sólo ese registro sea regresado. A continuación voy a poner un mensaje de espera para avisarle al usuario que la información se está cargando, como la carga es muy rápida voy a ponerle un “delay” para que veamos por más tiempo el mensaje.
//loading the data
Ext.Msg.wait('Loading... please wait!','Wait');
this.store.load({params:{param1:'value'}});
this.store.on('load',function(){
	//delay the message 2 seconds
	setTimeout(function(){ 
		Ext.Msg.hide(); // just to see the waiting message XD (don't do it in the real world)
	},2000);
});
Nota que he creado un “listener” para el evento “load” del store, donde definí una función que será ejecutada tan pronto como la información sea cargada en el store, dentro de esta función escondo el mensaje.

Conclusiones

En este tema además de mostrar como manipular un XML también se demostró la modularidad del Framework, si lo notaste, el código del tutorial anterior no fue modificado en lo absoluto, esto es por que estamos usando la misma información pero ahora esta contenida en un XML, así que simplemente se cambia la fuente de información y el resto de la aplicación sigue funcionando como si nada pasara, estas son una de las ventajas de utilizar Ext JS. Dudas, comentarios y sugerencias son bienvenidas y te pedimos de favor que votes por este tutorial en alguna de las redes sociales, con esto nos ayudas mantener este proyecto.

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?

11Comentarios

  • Avatar-6 Franco 23/04/2009

    no hay nada que decir este es el mejor blog e tuotrial que eh encontrado ...solo una preguna porque ya no pones video tutoriales creo que eran mucho mas amenos almenos yo vengo siguiendo cada uno de tus tutoriales y como que en ellos captaba mas rapidamente la idea por lo demas tienes 20/20 Saludos

    • Avatar-9 Crysfel 23/04/2009

      Lo que pasa estoy enfermo de la garganta y no puedo hablar bien :( por eso no he hecho los últimos videos, espero que para la próxima semana este mejor :) la idea principal es hacer los videos, pero por cuestiones ajenas a mi voluntad no he podido :(

    • Avatar-6 jose 13/05/2009

      me encanta, si tu supieras todo lo que te agradesco esto, un saludo y sigue haciendo tutoriales

      • Avatar-4 jose 13/05/2009

        una pregunta, ¿porque le pones a la funcion store el this?. E utilizado parte de este codigo para mi proyecto, estoy ahora mismo haciendo el login mediante un formulario que manda el usuario y el password y devuelve el php un xml. Los datos se mandan mediante la url y la direccion del php, ¿pero como recogeria el xml retornado por el php? en la opcion de success del boton, y ¿Como sabria si el la informacion del nodo respuesta es true ok o error para mostrar una cosa u otra? un saludo y gracias

        • Avatar-5 Crysfel 13/05/2009

          Puedes utilizar el listener "load", justo como lo he explicado en este tutorial, allí definirias lo que necesitas en este ejemplo solo oculté el mensaje, pero tu puedes hacer las comparaciones necesarias, etc.. si tienes mas dudas te invito a registrar en el foro para que podamos hablar mejor. saludos

          • Avatar-7 DrMartin 05/06/2009

            JSP!!! PLEASE!!

            • Avatar-6 gorrion 21/07/2009

              El atributo @active cuando se crea el registro es el que guarda la condicion true o false del XML? Es que como luego no se utiliza, tengo esa duda, me imagino que ya lo utilizaremos mas adelante. Gracias

              • Avatar-9 damian 04/03/2010

                donde se agrega este codigo que nombras ? no explica nada

                • Avatar-3 ramiromd 21/07/2011

                  Emmm....en un archivo JS, lo crear en blanco, pones este contenido, lo guardas, y lo llamas desde el html o php. Saludos

                  • Avatar-1 Luciano 18/07/2012

                    Gracias muy bueno!

                    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.