HTTPService
, y debe ser plasmada en un DataGrid
. En principio es simple, pero, ¿y si el resultado de la consulta genera resultados diferentes en el XML, tales como las columnas?. Imaginemos que en una consulta nos retorna el siguiente XML
:<?xml version="1.0" encoding="utf-8"?>
<vista2d>
<fila>
<Servicios>...</Servicios>
<Costes>...</Costes>
<Ventas>...</Ventas>
</fila>
...
</vista2d>
En otra consulta nos retorna este otro
XML
:<?xml version="1.0" encoding="utf-8"?>
<vista2d>
<fila>
<Objetivos>...</Objetivos>
<Ventas>...</Ventas>
<Gastos>...</Gastos>
<ROI>...</ROI>
<Desviacion>...</Desviacion>
</fila>
...
</vista2d>
En un
DataGrid
hemos de especificar implícitamente cada una de sus columnas para que éstas se visualicen. Al menos, cuando utilizamos MXML. Para poder generar DataGrids dinámicos, trabajaremos con ActionScript. En primer lugar, tendremos definido el
DataGrid
, el cual, al no conocer qué columnas va a tener, éstas no serán declaradas. Por tanto, el DataGrid
no contendrá columnas:<mx:DataGrid id="dgVista2D" width="100%" height="100%"/>
A continuación declararemos el servicio
HTTPService
, el cual será llamado mediante el método send()
. El código sería similar al siguiente: <s:HTTPService id="srvObtenerVista2D"
resultFormat="e4x"
method="GET" useProxy="false"
url="http://localhost:8080/ticube/SrvObtenerVista2D"
fault="getHTTPServiceFault(event)"
result="srvObtenerVista2DResult(event)"/>
Hemos de importar las siguientes clases para poder lanzar eventos en caso de que la llamada al
HTTPService
produzca algún error (fault
), o en el caso de que se haya procesado con éxito (result
):import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
En cada uno de estos casos, al producirse el evento, se ejecutará el método asociado. En el caso de que la llamada produjera un error (como en el caso de que no acceda a la URL, el servicio está caído, etc.), se lanzará un mensaje de error:
// Error en carga de datos HTTP
private function getHTTPServiceFault(event:FaultEvent):void {
Alert.show("Error: " + event.toString());
}
En el caso de que la llamada se efectuara correctamente, y retornara el
XML
correspondiente, éste se pasará como parámetro (event.result
). El código completo es el siguiente (a continuación se explicará en detalle):private function srvObtenerVista2DResult(event:ResultEvent):void {
var vxmll:XMLList = new XMLList(event.result.fila);
// Extraccion de columnas
if (vxmll.length()>0) {
var cols:Array = new Array(); // Crear array de columnas
for each(var element:XML in vxmll[0].elements()) {
// element.name retorna el titulo del elemento
// element.toString retorna el valor del elemento
cols.push(new DataGridColumn(element.name())); // Añadir columna al array
}
}
dgVista2D.columns = cols; // Asignar columnas al DataGrid
dgVista2D.validateNow(); // Validar y refrescar el DataGrid
// Convertir el XML retornado a ArrayCollection
// y cargar los datos en el DataGrid
var vxmllc:XMLListCollection = new XMLListCollection(vxmll);
var aResult:Array = vxmllc.toArray();
var acResult:ArrayCollection = acResult = new ArrayCollection(aResult);
dgVista2D.dataProvider=acResult;
}
El parámetro
event
recoge toda la información del evento, incluyendo el resultado (result
), el cual será el XML
retornado por el HTTPService
. private function srvObtenerVista2DResult(event:ResultEvent):void {
Cuando se accede al miembro
fila
de este XML
, éste retornará una lista (XMLList
) de elementos fila
, cada uno de los cuales es un XML
que contiene los elementos de nivel inferior (columnas y valores por columna). var vxmll:XMLList = new XMLList(event.result.fila);
Si esta lista posee información (el
XML
no vino vacío), se creará un array
(cols
) que almacenará los objetos de columna (objetos DataGridColumn
) que se añadirán al DataGrid
). Se recorren los elementos de la primera fila
(primer elemento de la lista), creando un objeto de columna, cuyo texto será el nombre del elemento substraído, y el cual será añadido al array. // Extraccion de columnas
if (vxmll.length()>0) {
var cols:Array = new Array(); // Crear array de columnas
for each(var element:XML in vxmll[0].elements()) {
// element.name retorna el titulo del elemento
// element.toString retorna el valor del elemento
cols.push(new DataGridColumn(element.name())); // Añadir columna al array
}
}
Finalizado el bucle, el array
cols
tendrá todas las columnnas (objetos DataGridColumn
), con el texto de cada elemento leído de la primera fila del XML. Ahora sólo queda asignar dicho array al DataGrid
, y a continuación validar dicho DataGrid
para que se actualice y visualice correctamente. dgVista2D.columns = cols; // Asignar columnas al DataGrid
dgVista2D.validateNow(); // Validar y refrescar el DataGrid
Por último, hay que asignar la información (datos) al
DataGrid
. Para ello, se transforman los datos de la lista (XMLList
) a una colección (XMLListCollection
), de ésta a un array
, y de éste a un objeto ArrayCollection
, el cual se puede asignar al DataGrid
, mediante su propiedad dataProvider
: // Convertir el XML retornado a ArrayCollection
// y cargar los datos en el DataGrid
var vxmllc:XMLListCollection = new XMLListCollection(vxmll);
var aResult:Array = vxmllc.toArray();
var acResult:ArrayCollection = acResult = new ArrayCollection(aResult);
dgVista2D.dataProvider=acResult;