7.3.1. 問(wèn)題
item renderer 需要訪(fǎng)問(wèn)它的父組件的一些數據。
7.3.2. 解決辦法實(shí)現IDropInListItemRenderer,通過(guò)drop-in renderer 訪(fǎng)問(wèn)它的父組件.
7.3.3. 討論實(shí)現了IDropInListItemRenderer 的renderer 不但能訪(fǎng)問(wèn)data 等一些傳入的數據,還能通過(guò)BaseListData類(lèi)型的一個(gè)屬性訪(fǎng)問(wèn)renderer 的父組件(如List 或DataGridColumn)。
mx.controls.listClasses.BaseListData 有如下屬性:
columnIndex : int當前是第幾列,當用戶(hù)用mouse 點(diǎn)擊List 或DataGrid 某個(gè)元素時(shí)這個(gè)屬性被賦值。第一列是1。(注意,這個(gè)值的含意是指選中列是當前可見(jiàn)表格中的第幾行,如果有橫向的滾動(dòng)條時(shí)要小心使用此屬性)(原文中指出第一列是1,但事實(shí)是0)
owner : IUIComponent這個(gè)drop-in itemRenderer 的所有者,即一個(gè)List 對象,或DataGridColumn 對象。(我認為原文這里是寫(xiě)錯了,owner 不可能是DataGridColumn 對象, 它只能是一個(gè)從ListBase擴展的類(lèi)型,我想作者這里是想寫(xiě)DataGrid)
rowIndex : int當前是第幾行,類(lèi)似columnIndex(這里要注意,這個(gè)屬性對于Tree 有特殊含意,這個(gè)值是根據當前所有展開(kāi)結點(diǎn)排列所得。)第一行是1。(原文中指出第一行是1,但事實(shí)是0)
uid : String用于唯一標識一個(gè)renderer 對象。
如果itemRenderer 實(shí)現了IDropInListItemRenderer 接口,即itemRenderer 會(huì )有set listData 和get listData 兩個(gè)方法,當這個(gè)itemRenderer 被使用時(shí),它會(huì )被實(shí)例化并利用set listData 傳數據給itemRenderer,這個(gè)數據就是我們在前邊提到的,BaseListData類(lèi)型的對象。在調用renderer 的set data 方法時(shí)我們可以根據listData 來(lái)得到擁有這個(gè)renderer 的容器,并通過(guò)一些判斷來(lái)決定對data 的處理。在這個(gè)過(guò)程中,我們還可以調用自己的一些方法。下面我們通過(guò)例子說(shuō)明listData 的用法。
+展開(kāi)-XML
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400"
height="50" implements="mx.controls.listClasses.IDropInListItemRenderer">
<mx:Script>
<![CDATA[
import mx.controls.DataGrid;
import mx.controls.List;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.controls.listClasses.BaseListData;
// store the list data item in case we want to do something with it
// later on
private var _listData:BaseListData;
[Bindable("dataChange")]
// a getter method.
public function get listData():BaseListData { return _listData; }
// a setter method,當BaseListData 數據被傳入之后renderer 就可以通過(guò)它自己的一
//些屬性訪(fǎng)問(wèn)擁有它的父組件中元素的數據,甚至可以調用父組件中的方法。
public function set listData(value:BaseListData):void {
_listData = value;
if (value.owner is DataGridColumn) {
trace("DataGridColumn");
} else if(value.owner is List) {
trace("List");
} else if
(value.owner is CustomDataGrid) {
trace("CustomDataGrid");
(value.owner as CustomDataGrid).checkInMethod(this);
}
}
override public function set data(value:Object):void {
nameTxt.text = value.name;
appearanceTxt.text = value.appearance;
}
]]>
</mx:Script>
<mx:Canvas backgroundColor="#3344ff">
<mx:Label id="nameTxt"/>
</mx:Canvas>
<mx:Label id="appearanceTxt"/>
</mx:VBox>
下邊是一個(gè)IDropInListRenderer 應用于一個(gè)用戶(hù)自定義的DataGrid:
+展開(kāi)-XML
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:cookbook="oreilly.cookbook.*">
<mx:List itemRenderer="oreilly.cookbook.IDropInListRenderer"
dataProvider="{DataHolder.genericCollectionOne}"/>
<!-- note that creating a custom component with a new
namespace, cookbook,
requires that our columns
are declared w/in the cookbook namespace -->
<cookbook:CustomDataGrid
dataProvider="{DataHolder.genericCollectionOne}">
<cookbook:columns>
<!-- since we're not declaring a dataField, the entire
data object
is passed to the renderer -->
<mx:DataGridColumn
itemRenderer="oreilly.cookbook.IDropInListRenderer"/>
<mx:DataGridColumn dataField="age"/>
</cookbook:columns>
</cookbook:CustomDataGrid>
</mx:HBox>
下邊是用戶(hù)自定義的DataGrid ,它有一個(gè)方法,checkInMethod ,這個(gè)方法是在renderer 的data 屬性被賦值時(shí)調用的。
+展開(kāi)-XML
<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
public function checkInMethod(obj:*):void {
trace("hello from my renderer"+obj);
}
]]>
</mx:Script>
</mx:DataGrid>
(譯者注)看完這節,大家可能還有些湖涂,我給大家總結一下:在第一節中我們說(shuō)過(guò),如果一個(gè)renderer 實(shí)現了IDropInListItemRenderer 接口,那么它就算是drop-in renderer 了。
IDropInListItemRenderer 接口中有兩個(gè)方法: set listData 和get listData 。flex對于renderer 有一種優(yōu)化的機制,就是:頁(yè)面中顯示幾個(gè)renderer 系統才實(shí)例幾個(gè)renderer,不顯示的就銷(xiāo)毀, 有新的顯示,如果重用也不夠時(shí),再new 。比如有一個(gè)DataGrid,它的數據源中有10 個(gè)對象,但頁(yè)面中的DataGrid 一次只顯示5 個(gè)(即有滾動(dòng)條),也就是說(shuō)系統在第一次顯示這個(gè)DataGrid 的時(shí)候一次性new 5 個(gè)renderer 當用戶(hù)向下拖動(dòng)滾動(dòng)條時(shí),下方會(huì )出現一條新數據,這時(shí)會(huì )再new 或重用一個(gè)renderer,上方那個(gè)移到顯示區外的數據對應的renderer 會(huì )被重用。當系統new 或重用一個(gè)renderer 之后如果這個(gè)renderer 是drop-in renderer,系統會(huì )調用set listData 方法,傳入一個(gè)BaseListData類(lèi)型的數據,BaseListData 數據中含有一個(gè)很有用的屬性owner,它是renderer 所在容器對象的一個(gè)引用,通過(guò)它我們可以得到容器的相關(guān)信息。接下來(lái)會(huì )調用set data方法,把data 傳入renderer 這時(shí)我們可以利用之前的BaseListData 數據中的信息控制data 數據。
本節內容相對來(lái)說(shuō)比較少,通過(guò)我填加的一些信息,希望大家能更容易理解。