Trabajo con DataProvider

DataProvider es un origen de datos que se puede utilizar para proporcionar datos a los componentes ComboBox, DataGrid, List y TileList. Cada una de estas clases de componente tiene una propiedad dataProvider a la que se puede asignar un objeto DataProvider para llenar con datos las celdas del componente. Normalmente, un proveedor de datos es una colección de datos como, por ejemplo, un objeto Array o XML.

Creación de un objeto DataProvider

Para los componentes ComboBox, List y TileList se puede crear un objeto DataProvider mediante el parámetro dataProvider en el entorno de edición. El componente DataGrid no tiene un parámetro dataProvider en el inspector de propiedades, ya que puede tener varias columnas y, en consecuencia, su proveedor de datos es más complejo. Asimismo, se puede utilizar ActionScript para crear un objeto DataProvider para estos componentes y para DataGrid.

Uso del parámetro dataProvider

Se puede crear un proveedor de datos sencillo para los componentes ComboBox, List y TileList haciendo clic en el parámetro dataProvider de la ficha Parámetros, en el inspector de propiedades o en el inspector de componentes.

Si se hace doble clic en la celda de valor, que inicialmente muestra un objeto Array vacío, se abrirá el cuadro de diálogo Valores, que permite introducir varios valores de etiqueta y datos para crear el proveedor de datos.

Cuadro de diálogo Valores para dataProvider

Haga clic en el signo más para añadir un elemento a dataProvider. Haga clic en el signo menos para eliminar un elemento. Haga clic en la tecla de flecha arriba para subir un elemento seleccionado por la lista, o bien haga clic en la tecla de flecha abajo para bajarlo. En la ilustración siguiente se muestra un cuadro de diálogo Valores que crea una lista de nombres y cumpleaños de niños.

Cuadro de diálogo Valores con datos

El objeto Array que se crea consta de pares de campos de etiqueta y valor. Los campos de etiqueta son label y data y los campos de valor son los nombres de los niños y sus cumpleaños. El campo de etiqueta identifica el contenido que aparece en List, que en este caso está formado por los nombres de los niños. El componente ComboBox resultante tiene el siguiente aspecto:

Componente ComboBox llenado por DataProvider

Cuando termine de añadir los datos, haga clic en Aceptar para cerrar el cuadro de diálogo. El objeto Array del parámetro dataProvider ya está lleno con los elementos que se han creado.

Ver gráfico a tamaño completo
Parámetro dataProvider con datos

Se puede acceder a los valores de etiqueta y datos creados utilizando ActionScript para acceder a la propiedad dataProvider del componente.

Creación de un objeto DataProvider con ActionScript

Se puede crear un objeto DataProvider creando los datos en un objeto Array o XML y proporcionando el objeto como el parámetro value al constructor de DataProvider.

Nota: en ActionScript 3.0, no se puede asignar un objeto Array o XML directamente a una propiedad dataProvider, ya que la propiedad se define como objeto DataProvider y sólo puede recibir un objeto de tipo DataProvider.

En el ejemplo siguiente se llena un componente List, que es una columna de filas, con los nombres de varios niños y sus cumpleaños. En el ejemplo se define la lista en el objeto Array items y se proporciona como parámetro cuando se crea la instancia de DataProvider ( new DataProvider(items)) y se asigna a la propiedad dataProvider del componente List.

import fl.controls.List; 
import fl.data.DataProvider; 
 
var aList:List = new List(); 
var items:Array = [ 
{label:"David", data:"11/19/1995"}, 
{label:"Colleen", data:"4/20/1993"}, 
{label:"Sharon", data:"9/06/1997"}, 
{label:"Ronnie", data:"7/6/1993"}, 
{label:"James", data:"2/15/1994"}, 
]; 
aList.dataProvider = new DataProvider(items); 
addChild(aList); 
aList.move(150,150);

El objeto Array consta de pares de campos de etiqueta y valor. Los campos de etiqueta son label y data y los campos de valor son los nombres de los niños y sus cumpleaños. El campo de etiqueta identifica el contenido que aparece en List, que en este caso está formado por los nombres de los niños. El componente List resultante tiene el siguiente aspecto:

Componente List llenado por DataProvider

El valor del campo de datos está disponible cuando el usuario selecciona un elemento de la lista haciendo clic en él o desencadenando un evento change. En el ejemplo siguiente se añade un componente TextArea ( aTa ) y un controlador de eventos ( changeHandler ) al ejemplo anterior para mostrar el cumpleaños del niño cuando el usuario selecciona un nombre del componente List.

import fl.controls.List; 
import fl.controls.TextArea; 
import flash.events.Event; 
import fl.data.DataProvider; 
 
var aList:List = new List(); 
var aTa:TextArea = new TextArea(); 
var items:Array = [ 
{label:"David", data:"1/19/1995"}, 
{label:"Colleen", data:"4/20/1993"}, 
{label:"Sharon", data:"9/06/1994"}, 
{label:"Ronnie", data:"7/6/1993"}, 
{label:"James", data:"2/15/1994"}, 
]; 
aList.dataProvider = new DataProvider(items); 
 
addChild(aList); 
addChild(aTa); 
 
aList.move(150,150); 
aTa.move(150, 260); 
 
aList.addEventListener(Event.CHANGE, changeHandler); 
 
function changeHandler(event:Event):void { 
    aTa.text = event.target.selectedItem.data; 
};

A continuación, cuando el usuario selecciona el nombre del niño en List, el cumpleaños de dicho niño se muestra en TextArea tal como se muestra en la ilustración siguiente. Esto se consigue con la función changeHandler() cuando establece la propiedad text de TextArea ( aTa.text ) en el valor del campo de datos del elemento seleccionado ( event.target.selectedItem.data ). La propiedad event.target es el objeto que ha activado el evento, que en este caso es el componente List.

Visualización del campo de datos de DataProvider de un componente List

Se pueden incluir datos que no sean texto en DataProvider. En el ejemplo siguiente se incluyen componentes MovieClip en un DataProvider que proporciona datos a un componente TileList. Se crea el objeto DataProvider llamando a addItem() para añadir todos los elementos una vez que se crea el componente MovieClip, un cuadro de color.

import fl.data.DataProvider; 
import flash.display.DisplayObject; 
 
var aBox:MovieClip = new MovieClip(); 
var i:uint = 0; 
var colors:Array = new Array(0x00000, 0xFF0000, 0x0000CC, 0x00CC00, 0xFFFF00); 
var colorNames:Array = new Array("Midnight", "Cranberry", "Sky", "Forest", "July"); 
var dp:DataProvider = new DataProvider(); 
for(i=0; i < colors.length; i++) { 
    drawBox(aBox, colors[i]);    // draw box w next color in array 
    dp.addItem( {label:colorNames[i], source:aBox} ); 
} 
aTl.dataProvider = dp; 
aTl.columnWidth = 110; 
aTl.rowHeight = 130; 
aTl.setSize(280,150); 
aTl.move(150, 150); 
aTl.setStyle("contentPadding", 5); 
 
function drawBox(box:MovieClip,color:uint):void { 
            box.graphics.beginFill(color, 1.0); 
            box.graphics.drawRect(0, 0, 100, 100); 
            box.graphics.endFill();        

También se pueden utilizar datos XML (en lugar de un conjunto) para llenar un objeto DataProvider. Por ejemplo, en el código siguiente se almacenan datos en un objeto XML denominado employeesXML , y luego se pasa dicho objeto como el parámetro de valor de la función constructora DataProvider() :

import fl.controls.DataGrid; 
import fl.data.DataProvider; 
 
var aDg:DataGrid = new DataGrid(); 
addChild(aDg); 
 
var employeesXML:XML =  
    <employees> 
        <employee Name="Edna" ID="22" /> 
        <employee Name="Stu" ID="23" /> 
    </employees>; 
 
var myDP:DataProvider = new DataProvider(employeesXML); 
 
aDg.columns = ["Name", "ID"]; 
aDg.dataProvider = myDP;

Se pueden proporcionar datos como atributos de los datos XML, como en el código anterior, o bien como propiedades de dichos datos, tal como se muestra en el código siguiente:

var employeesXML:XML =  
    <employees> 
        <employee> 
            <Name>Edna</Name> 
            <ID>22</ID> 
        </employee> 
        <employee> 
            <Name>Stu</Name> 
            <ID>23</ID> 
        </employee> 
    </employees>;

El objeto DataProvider también tiene un conjunto de métodos y propiedades que permiten acceder a él y manipularlo. Se puede utilizar la API de DataProvider para añadir, eliminar, reemplazar, ordenar y combinar elementos en un objeto DataProvider.

Manipulación de un objeto DataProvider

Se pueden añadir elementos a un objeto DataProvider con los métodos addItem() y addItemAt() . En el ejemplo siguiente se añaden elementos que introduce el usuario en el campo de texto de un componente ComboBox editable. Se supone que el componente ComboBox se ha arrastrado al escenario y se le ha asignado el nombre de instancia aCb .

import fl.data.DataProvider; 
import fl.events.ComponentEvent; 
 
var items:Array = [ 
{label:"Roger"}, 
{label:"Carolyn"}, 
{label:"Darrell"}, 
{label:"Rebecca"}, 
{label:"Natalie"}, 
{label:"Mitchell"}, 
]; 
aCb.dataProvider = new DataProvider(items); 
     
aCb.addEventListener(ComponentEvent.ENTER, newItemHandler); 
 
function newItemHandler(event:ComponentEvent):void { 
    var newRow:int = event.target.length + 1; 
        event.target.addItemAt({label:event.target.selectedLabel}, 
        event.target.length); 
}

Asimismo, se pueden reemplazar y eliminar elementos de un componente a través de su DataProvider. En el ejemplo siguiente se implementan dos componentes List diferentes, listA y listB , y se proporciona un componente Button denominado Sync. Cuando el usuario hace clic en Button, el ejemplo utiliza el método replaceItemAt() para reemplazar los elementos de listB con los elementos de listA . Si la longitud de listA es mayor que la de listB , el ejemplo llama al método addItem() para añadir elementos adicionales a listB . Si la longitud de listB es mayor que la de listA , el ejemplo llama al método removeItemAt() para eliminar los elementos adicionales de listB .

// Requires the List and Button components to be in the library 
 
import fl.controls.List; 
import fl.controls.Button; 
import flash.events.Event; 
import fl.data.DataProvider; 
 
var listA:List = new List(); 
var listB:List = new List(); 
var syncButton:Button = new Button(); 
syncButton.label = "Sync"; 
 
var itemsA:Array = [ 
{label:"David"}, 
{label:"Colleen"}, 
{label:"Sharon"}, 
{label:"Ronnie"}, 
{label:"James"}, 
]; 
var itemsB:Array = [ 
{label:"Roger"}, 
{label:"Carolyn"}, 
{label:"Darrell"}, 
{label:"Rebecca"}, 
{label:"Natalie"}, 
{label:"Mitchell"}, 
]; 
listA.dataProvider = new DataProvider(itemsA); 
listB.dataProvider = new DataProvider(itemsB); 
 
addChild(listA); 
addChild(listB); 
addChild(syncButton); 
 
listA.move(100, 100); 
listB.move(250, 100); 
syncButton.move(175, 220); 
 
syncButton.addEventListener(MouseEvent.CLICK, syncHandler); 
 
function syncHandler(event:MouseEvent):void { 
    var i:uint = 0; 
    if(listA.length > listB.length) {     //if listA is longer, add items to B 
        while(i < listB.length) { 
            listB.dataProvider.replaceItemAt(listA.dataProvider.getItemAt(i), i); 
            ++i; 
        } 
        while(i < listA.length) { 
            listB.dataProvider.addItem(listA.dataProvider.getItemAt(i++)); 
        } 
    } else if(listA.length == listB.length) { //if listA and listB are equal length 
        while(i < listB.length) { 
            listB.dataProvider.replaceItemAt(listA.dataProvider.getItemAt(i), i); 
            ++i; 
        } 
    } else {                //if listB is longer, remove extra items from B 
        while(i < listA.length) { 
            listB.dataProvider.replaceItemAt(listA.dataProvider.getItemAt(i), i); 
            ++i; 
        } 
        while(i < listB.length) { 
            listB.dataProvider.removeItemAt(i++); 
        } 
    } 
}

También se pueden realizar combinaciones con un objeto DataProvider y ordenarlo mediante los métodos merge() , sort() y sortOn() . En el ejemplo siguiente se llenan dos instancias de DataGrid ( aDg y bDg ) con calendarios parciales de dos equipos de fútbol. Se añade un componente Button con la etiqueta Combinar y cuando el usuario hace clic en él, el controlador de eventos ( mrgHandler ) combina el calendario de bDg con el calendario de aDg , y ordena el componente DataGrid resultante en la columna Nombre.

import fl.data.DataProvider; 
import fl.controls.DataGrid; 
import fl.controls.Button; 
 
var aDg:DataGrid = new DataGrid(); 
var bDg:DataGrid = new DataGrid(); 
var mrgButton:Button = new Button(); 
addChild(aDg); 
addChild(bDg); 
addChild(mrgButton); 
bldRosterGrid(aDg); 
bldRosterGrid(bDg); 
var aRoster:Array = new Array(); 
var bRoster:Array = new Array(); 
aRoster = [ 
        {Name:"Wilma Carter", Bats:"R", Throws:"R", Year:"So", Home: "Redlands, CA"},  
        {Name:"Sue Pennypacker", Bats:"L", Throws:"R", Year:"Fr", Home: "Athens, GA"}, 
        {Name:"Jill Smithfield", Bats:"R", Throws:"L", Year:"Sr", Home: "Spokane, WA"}, 
        {Name:"Shirley Goth", Bats:"R", Throws:"R", Year:"Sr", Home: "Carson, NV"} 
]; 
bRoster = [ 
        {Name:"Angelina Davis", Bats:"R", Throws:"R", Year:"So", Home: "Odessa, TX"}, 
        {Name:"Maria Santiago", Bats:"L", Throws:"L", Year:"Sr", Home: "Tacoma, WA"}, 
        {Name:"Debbie Ferguson", Bats:"R", Throws:"R", Year: "Jr", Home: "Bend, OR"} 
]; 
aDg.dataProvider = new DataProvider(aRoster); 
bDg.dataProvider = new DataProvider(bRoster); 
aDg.move(50,50); 
aDg.rowCount = aDg.length; 
bDg.move(50,200); 
bDg.rowCount = bDg.length; 
mrgButton.label = "Merge"; 
mrgButton.move(200, 315); 
mrgButton.addEventListener(MouseEvent.CLICK, mrgHandler); 
 
function bldRosterGrid(dg:DataGrid){ 
    dg.setSize(400, 300); 
    dg.columns = ["Name", "Bats", "Throws", "Year", "Home"]; 
    dg.columns[0].width = 120; 
    dg.columns[1].width = 50; 
    dg.columns[2].width = 50; 
    dg.columns[3].width = 40; 
    dg.columns[4].width = 120; 
}; 
 
function mrgHandler(event:MouseEvent):void { 
    aDg.dataProvider.merge(bDg.dataProvider); 
    aDg.dataProvider.sortOn("Name"); 
}

Para obtener más información, consulte la clase DataProvider en la Referencia de ActionScript 3.0 .