miércoles, 3 de noviembre de 2010

Flex/AIR: Creación de objetos en tiempo de ejecución

Dentro de las posibilidades que nos ofrece Flex, una de las más potentes y útiles es la de crear objetos en tiempo de ejecución. Hay muchos casos de los que se podría hablar, pero en este post voy a comentar uno que me ha surgido, y que seguramente os pueda surgir a vosotros también.

El caso del que voy a hablar trata de cuando se obtienen datos de alguna fuente, de forma dinámica, es decir, que pueden llegar con nombres de campo y con valores variopintos y distintos. Casos como éste puede ocurrir cuando se quiere crear un mapeo automático de tablas o de consultas a bases de datos, de un XML impredecible, de un JSON, etc. En este escenario, de nada nos sirve predecir una clase con sus propiedades.

Para crear un objeto que contenga estos datos dinámicos, primeramente hay que definir una variable de tipo Object:

var o:Object = new Object();

Para crear una propiedad dinámica con su respectivo valor, la declaración sería de la siguiente manera:

o["propiedad"] = valor;

Para acceder al valor de la propiedad:

o["propiedad"]

Cada vez que se agrega una propiedad al objeto, ésta es accesible mediante una enumeración. Para recorrer las propiedades definidas en el objeto:

for (var detalle:* in o) {
  ...
}


La variable detalle contiene el nombre de la propiedad. Gracias a este valor se puede acceder a la propiedad y, por tanto, también a su valor:

for (var detalle:* in o) {
  Alert.show(lbCaracteristicas.text +
    "-["+detalle+"]: "+o[detalle];
}


A continuación, un código de ejemplo para experimentar con todo lo aportado en este post:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:s="library://ns.adobe.com/flex/spark"
 xmlns:mx="library://ns.adobe.com/flex/mx"
 creationComplete="init()">

 <mx:HBox>
  <s:Label id="lbPropiedad" fontWeight="bold"/>
  <s:Label id="lbValor" fontWeight="normal"/>
  <s:Label id="lbCaracteristicas" fontStyle="italic"/>
 </mx:HBox>

 <fx:Script>
  <![CDATA[
   private function init():void {
    var propiedad1:String = "nombre";
    var valor1:String = "Rafael Hernamperez";
    var propiedad2:String = "edad";
    var valor2:int = 40;
    var info:Object = new Object();
    info[propiedad1] = valor1;
    info[propiedad2] = valor2;
    lbPropiedad.text = propiedad1;
    lbValor.text = info[propiedad1];

    for (var detalle:* in info) {
     lbCaracteristicas.text = lbCaracteristicas.text +
      "-["+detalle+"]: "+info[detalle];
    }
   }
  ]]>
 </fx:Script>
</s:Application>


El resultado debería ser el siguiente:

nombre  Rafael Hernamperez  -[nombre]: Rafael Hernamperez-[edad]: 40