Datagrids
dinámicos (http://rafinguer.blogspot.com/2010/11/flexair-datagrids-dinamicos.html), expusimos un ejemplo práctico en base a un XML
clásico y básico. El planteamiento expuesto contempla que el nombre de cada elemento es también el texto de la columna. Pero, ¿y si el texto de la columna debe contener caracteres no alfabéticos, espacios, signos, etc.? Entonces no nos vale. Hemos de replantear el XML
, por ejemplo, de la siguiente manera:<?xml version="1.0" encoding="utf-8"?>
<vista2d>
<fila>
<columna nombre="Costes financieros">99898.95</columna>
<columna nombre="Costes globales">78700.87</columna>
<columna nombre="Costes internos">54980.76</columna>
</fila>
...
</vista2d>
Las columnas serán todas elementos
columna
, y el nombre de la columna vendrá dado por el atributo nombre
. Por tanto, ha de recogerse el atributo, no el nombre del elemento. Esto plantea un problema, pues a la hora de crear la columna (mediante DataGridColumn
), hay que asignar el argumento como texto de cabecera (propiedad headerText
), pero la creación de la misma requiere de un nombre. Al ser dinámico, también ha de tener un nombre único. Esto se podría realizar mediante el siguiente código:// Extraccion de columnas
var cols:Array = new Array(); // Crear array de columnas
var iCol:int=0;
for each(var element:XML in vxmll[0].elements()) {
var col:DataGridColumn = new DataGridColumn("c"+iCol);
col.headerText=element.attribute("nombre");
cols.push(col);
iCol++;
}
dgVista2D.columns = cols; // Asignar columnas al DataGrid
dgVista2D.validateNow(); // Validar y refrescar el DataGrid
Como se puede comprobar, hay un contador de columnas (de 0 a n), el cual servirá para asignar el nombre a la columna ("c1", "c2", "c3", etc.)
El problema que viene a continuación es que si se convierte los datos del
XML
almacenado en vxmll
a un ArrayCollection
, y asignárselo al DataGrid
, no aparecerá ningún dato. ¿El motivo? El nombre de las columnas.La solución está en crear un
ArrayCollection
que contenga un objeto por cada fila, que contenga tantas propiedades como columnas tenga, y que dichas propiedades se llamen igual que las columnas. Como todo es dinámico, habrá que crear objetos en tiempo de ejecución (ver anterior post: http://rafinguer.blogspot.com/2010/11/flexair-creacion-de-objetos-en-tiempo.html).El siguiente código realizará la conversión correcta para que el
DataGrid
muestre correctamente los datos:// Procesamiento de los datos
acResult = new ArrayCollection();
// Recorre las filas
for each(var elem:XML in vxmll) {
// Recorre las columnas
iCol = 0;
var o:Object = new Object();
for each(var subelement:XML in elem.elements()) {
o["c"+iCol]=subelement.toString();
iCol++;
}
acResult.addItem(o);
}
dgVista2D.dataProvider=acResult;
El código completo para la función
srvObtenerVista2DResult()
es el siguiente:private function srvObtenerVista2DResult(event:ResultEvent):void {
var vxmll:XMLList = new XMLList(event.result.fila);
// Si hay datos
if (vxmll.length()>0) {
// Extraccion de columnas
var cols:Array = new Array(); // Crear array de columnas
var iCol:int=0;
for each(var element:XML in vxmll[0].elements()) {
var col:DataGridColumn = new DataGridColumn("c"+iCol);
col.headerText=element.attribute("nombre");
cols.push(col);
iCol++;
}
dgVista2D.columns = cols; // Asignar columnas al DataGrid
dgVista2D.validateNow(); // Validar y refrescar el DataGrid
// Procesamiento de los datos
acResult = new ArrayCollection();
// Recorre las filas
for each(var elem:XML in vxmll) {
// Recorre las columnas
iCol = 0;
var o:Object = new Object();
for each(var subelement:XML in elem.elements()) {
o["c"+iCol]=subelement.toString();
iCol++;
}
acResult.addItem(o);
}
dgVista2D.dataProvider=acResult;
}
}