使用 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 組件建立簡單的資料提供者。

如果您按兩下值儲存格 (一開始顯示的是空白「陣列」),將會開啟「值」對話方塊,讓您可以輸入多個標籤和資料值來建立資料提供者。

dataProvider 的「值」對話方塊

按一下加號可以將項目加入到 dataProvider。按一下減號可以刪除項目。按一下向上鍵可以將清單中選取的項目往上移動一個位置;按一下向下鍵可以將清單中選取的項目往下移動一個位置。下圖顯示可以建立孩童姓名和生日清單的「值」對話方塊。

包含資料的「值」對話方塊

您建立的 Array 是由一對標籤和值欄位組成。標籤欄位是 label data ,而值欄位則是孩童的姓名和他們的生日。標籤欄位可以辨識 List 中顯示的內容,在這個範例中是孩童的姓名。最後的 ComboBox 看起來會像這樣:

由 DataProvider 填入的 ComboBox

完成加入資料後,請按一下「確定」關閉對話方塊。dataProvider 參數中的 Array 現在已經填入您建立的項目。

包含資料的 dataProvider 參數

使用 ActionScript 存取組件的 dataProvider 屬性就可以存取您建立的標籤和資料值。

使用 ActionScript 建立 DataProvider

您可以在 Array 或 XML 物件中建立資料,並提供該物件做為 DataProvider 建構函式的 value 參數,以便建立 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 是由一對標籤和值欄位組成。標籤欄位是 label data ,而值欄位則是孩童的姓名和他們的生日。標籤欄位可以辨識 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 可以接受文字以外的資料。下列範例會將 MovieClips 加入 DataProvider 以提供資料給 TileList。範例會在建立彩色方塊 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 資料的特質 (如同上一段程式碼一般),或是做為 XML 資料的屬性 (如下列程式碼所示):

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 組件: listA listB ,並提供一個已命名為 Sync 的 Button。當使用者按一下 Button 後,範例會使用 replaceItemAt() 方法,以 listA 中的項目取代 listB 中的項目。如果 listA 的長度大於 listB ,範例會呼叫 addItem() 方法將額外的項目加入到 listB 。如果 listB 的長度大於 listA ,範例會呼叫 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 實體 ( aDg bDg )。範例中會加入標示 Merge 的 Button,當使用者按一下後,事件處理常式 ( mrgHandler ) 就會將 bDg 的名冊與 aDg 的名冊合併,然後對合併後 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"); 
}

如需詳細資訊,請參閱「DataProvider 類別」(位於「 ActionScript 3.0 參考 )。