使用 DataProvider

DataProvider 是可以用来向 ComboBox、DataGrid、List 和 TileList 组件提供数据的数据源。上述每个组件类都有一个 dataProvider 属性,您可以将 DataProvider 对象赋给该属性以用数据填充该组件的单元格。通常情况下,数据提供程序是一个数据集合,如 Array 或 XML 对象。

创建 DataProvider

对于 ComboBox、List 和 TileList 组件,您可以在创作环境中使用 dataProvider 参数来创建 DataProvider。DataGrid 组件在“属性”检查器中没有提供 dataProvider 参数,原因是它可能有多个列,所以它的数据提供程序比较复杂。您还可以使用 ActionScript 为这些组件以及 DataGrid 创建 DataProvider。

使用 dataProvider 参数

通过单击“属性”检查器或“组件”检查器的“参数”选项卡中的 dataProvider 参数,可以为 ComboBox、List 和 TileList 组件创建简单的数据提供程序。

如果双击值单元格(它最初显示一个空的 Array),将打开“值”对话框,可在此对话框中输入多个标签和数据值来创建数据提供程序。

dataProvider 的“值”对话框

单击加号可向 dataProvider 添加项目。单击减号可删除项目。单击向上箭头可在列表中将所选项目上移,单击向下箭头可在列表中将所选项目下移。下图显示的“值”对话框创建一个由孩子的姓名及生日组成的列表。

带有数据的“值”对话框

您创建的 Array 由若干对标签和值字段组成。标签字段为 labeldata,值字段为孩子的姓名及生日。标签字段标识 List 中显示的内容,在本例中即为孩子的姓名。产生的 ComboBox 如下所示:

由 DataProvider 填充的 ComboBox

添加完数据后,单击“确定”以关闭该对话框。现在,已用您创建的项目填充了 dataProvider 参数中的 Array。

包含数据的 dataProvider 参数

通过使用 ActionScript 访问组件的 dataProvider 属性,可以访问您创建的标签和数据值。

使用 ActionScript 创建 DataProvider

通过在 Array 或 XML 对象中创建数据并将该对象作为 value 参数提供给 DataProvider 构造函数,可以创建 DataProvider。

注: 在 ActionScript 3.0 中,无法直接将 Array 或 XML 对象赋给 dataProvider 属性,原因是此属性定义为 DataProvider 对象,因而只能接收 DataProvider 类型的对象。

下面的示例用若干孩子的姓名及生日填充由仅包含一列的若干行组成的 List 组件。此示例在 items Array 中定义此列表,并在创建 DataProvider 实例 (new DataProvider(items)) 时将它作为参数提供,从而将它赋给此 List 组件的 dataProvider 属性。

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);

Array 由若干对标签和值字段组成。标签字段为 labeldata,值字段为孩子的姓名及生日。标签字段标识 List 中显示的内容,在本例中即为孩子的姓名。产生的 List 如下所示:

由 DataProvider 填充的 List

当用户选择列表中的某一项目(通过单击该项目,此时会引发 change 事件)时可以使用数据字段的值。下面的示例向上一示例添加一个 TextArea (aTa) 和一个事件处理函数 (changeHandler),以便在用户选择此 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; 
};

现在,如果用户选择此 List 中某个孩子的姓名,此孩子的生日就会显示在此 TextArea 中,如下图所示。changeHandler() 函数将此 TextArea (aTa.text) 的 text 属性设置为所选项目中的数据字段 (event.target.selectedItem.data) 的值,从而实现此过程。event.target 属性是触发此事件的对象,在本例中即为此 List。

显示 List 的 DataProvider 中的数据字段

可以将非文本数据包含在 DataProvider 中。下面的示例将 MovieClip 包含在为 TileList 提供数据的 DataProvider 中。它在创建 MovieClip(一个带颜色的框)之后,通过调用 addItem() 添加每个项目来构建 DataProvider。

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();        

也可以使用 XML 数据(而非数组)来填充 DataProvider 对象。例如,下面的代码将数据存储在一个名为 employeesXML 的 XML 对象中,然后将该对象作为 DataProvider() 构造函数的 value 参数传递:

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;

可以将数据作为 XML 数据的属性 (attribute) 提供,如上一段代码所示;也可以将数据作为 XML 数据的属性 (property) 提供,如下面的代码所示:

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

DataProvider 还有一组用来访问和操作它的方法和属性。可以使用 DataProvider API 在 DataProvider 中添加项目、删除项目、替换项目、对项目排序以及合并项目。

操作 DataProvider

使用 addItem()addItemAt() 方法可以将项目添加到 DataProvider 中。下面的示例添加用户在可编辑的 ComboBox 的文本字段中输入的项目。在此示例中,假定已将一个 ComboBox 拖到舞台上并已为其指定实例名称 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); 
}

还可以通过组件的 DataProvider 替换和删除组件中的项目。下面的示例实现了两个单独的 List 组件 listAlistB,并提供了一个标签为“Sync”的 Button。用户单击此 Button 时,此示例将使用 replaceItemAt() 方法用 listA 中的项目替换 listB 中的项目。如果 listAlistB 长,此示例将调用 addItem() 方法向 listB 添加额外的项目。如果 listBlistA 长,此示例将调用 removeItemAt() 方法删除 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++); 
        } 
    } 
}

还可以使用 merge()sort()sortOn() 方法合并 DataProvider 以及对其进行排序。下面的示例用两个垒球队的部分花名册填充两个 DataGrid 实例(aDgbDg)。它添加一个标签为 Merge 的 Button,当用户单击此 Button 时,事件处理函数 (mrgHandler) 将合并 bDgaDg 的花名册,并按 Name 列对得到的 DataGrid 进行排序。

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"); 
}

有关详细信息,请参阅 Adobe ActionScript 3.0 Reference for the Adobe Flash Platform 中的 DataProvider 类。