理解Flex itemRenderer(3)--通信
在本系列的第 2 部分中, 我向您展示了如何使用 MXML 和 ActionScript 創(chuàng)建外部 itemRenderer。在我用過(guò)的示例中, 有一個(gè)調(diào)度自定事件 BuyBookEvent 的 Button-這樣應(yīng)用程序可以對(duì)它作出響應(yīng)。本文進(jìn)一步討論與 itemRenderer 的通信。
我堅(jiān)信有一條規(guī)則是永遠(yuǎn)不能違背的: 不能抓住 itemRenderer 的實(shí)例不放, 更改它 (設(shè)置公共屬性) 或調(diào)用它的公共方法。這對(duì)我而言是一個(gè)禁忌。itemRenderer 是很難弄清的, 我在第 1 部分中說(shuō)到了其中的緣由: itemRenderer 是循環(huán)使用的。抓住一個(gè)會(huì)破壞 Flex 框架。
請(qǐng)將這條規(guī)則謹(jǐn)記在心, 您可以使用 itemRenderer 完成以下操作:
- itemRenderer 可以通過(guò)它的列表所有者調(diào)度事件。 (您已經(jīng)看到過(guò)冒泡; 這個(gè)做法更好, 接下來(lái)您就會(huì)看到。)
- itemRenderer 可以使用靜態(tài)類成員。其中包括 Application.application。如果您的值“全局”存儲(chǔ)在應(yīng)用程序?qū)ο笾? 您可以通過(guò)這種方式獲得它們。
- itemRenderer 可以使用擁有它的列表的公共成員。接下來(lái)您就會(huì)看到。
- itemRenderer 可以使用數(shù)據(jù)記錄中的任何內(nèi)容。例如, 記錄中的某個(gè)項(xiàng)目不用于直接顯示, 但它卻影響 itemRenderer 的行為方式。
動(dòng)態(tài)更改 itemRenderer
以下是上一篇文章中用于 TileList 的 MXML itemRenderer。我將使它對(duì)外部源 (我將這個(gè)文件稱為 BookItemRenderer.mxml) 的更改作出反應(yīng), 從而使它更生動(dòng):
<?xml version="1.0" encoding="utf-8"?> <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="250" height="115" ><mx:Script><![CDATA[ ]]></mx:Script><mx:Image id="bookImage" source="{data.image}" /><mx:VBox height="115" verticalAlign="top" verticalGap="0"><mx:Text text="{data.title}" fontWeight="bold" width="100%"/><mx:Spacer height="20" /><mx:Label text="{data.author}" /><mx:Label text="Available {data.date}" /><mx:Spacer height="100%" /><mx:HBox width="100%" horizontalAlign="right"><mx:Button label="Buy" fillColors="[0x99ff99,0x99ff99]"><mx:click><![CDATA[var e:BuyBookEvent = new BuyBookEvent();e.bookData = data;dispatchEvent(e);]]></mx:click></mx:Button></mx:HBox></mx:VBox> </mx:HBox>假設(shè)您在 TileList 中顯示一個(gè)商品目錄。您還有一個(gè) Slider (不屬于 itemRenderer), 它允許用戶給出一個(gè)價(jià)格范圍; 在此范圍之外的所有商品應(yīng)變灰 (itemRenderer 的 alpha 值應(yīng)改變)。您需要告知所有 itemRenderer 標(biāo)準(zhǔn)已改變, 這樣它們可以修改自己的 alpha 值。
覆蓋 set data 可能如下:
override public function set data( value:Object ) : void {super.data = value;if( data.price < criteria ) alpha = 0.4;else alpha = 1; }問(wèn)題是: 如何更改標(biāo)準(zhǔn)值?itemRenderer 的“最佳做法”是始終讓它們處理為自己手頭的數(shù)據(jù)。在本例中, 將測(cè)試標(biāo)準(zhǔn)作為數(shù)據(jù)的一部分不可能也不切實(shí)際。所以這在數(shù)據(jù)外留下了一個(gè)位置。您有兩個(gè)選擇:
- 列表本身的一部分。即, 您的列表 (List、DataGrid、TileList 或其他) 可以是擴(kuò)展列表控制并且將這個(gè)標(biāo)準(zhǔn)作為公共成員的類。
- 作為全局?jǐn)?shù)據(jù)的應(yīng)用程序的一部分。
我選擇第一個(gè): 擴(kuò)展一個(gè)類并將這個(gè)標(biāo)準(zhǔn)作為該類的一部分。畢竟, 這個(gè)類將用于顯示數(shù)據(jù), 而標(biāo)準(zhǔn)是顯示內(nèi)容的一部分。對(duì)于本例, 我將擴(kuò)展 TileList 并將標(biāo)準(zhǔn)作為公共數(shù)據(jù)成員。
package {import mx.controls.TileList;public class CatalogList extends TileList{public function CatalogList(){super();}private var _criteria:Number = 10;public function get critera() : Number{return _criteria;}public function set criteria( value:Number ) : void{_criteria = value;} } }這個(gè)辦法是, itemRenderer 外的控制可以通過(guò)更改列表控制上的這個(gè)屬性來(lái)修改標(biāo)準(zhǔn)。
listData
itemRenderer 可以訪問(wèn)另一塊數(shù)據(jù): 列表本身的相關(guān)信息以及它們渲染哪個(gè)行哪個(gè)列 (如果在面向列的控制中)。這稱為 listData, 在 BookItemRenderer.mxml itemRenderer 示例中可以這樣使用它:
override public function set data( value:Object ) : void {super.data = value;var criteria:Number = (listData.owner as MyTileList).criteria;if( data.price < criteria ) alpha = 0.4; else alpha = 1; }將這個(gè)代碼放入上述示例 BooktItemRenderer.mxml 代碼的 <mx:Script> 塊中。
itemRenderer 的 listData property 有一個(gè) owner 字段, 它是 itemRenderer 所屬的控制。在本例中, 所有者是 MyTileList 控制-我的 TileList 擴(kuò)展。將所有者字段轉(zhuǎn)換為 MyTileList 即可取走標(biāo)準(zhǔn)。
IDropInListItemRenderer
當(dāng) itemRenderer 類實(shí)施 IDropInListItemRenderer 接口時(shí), 即可訪問(wèn) listData。不幸的是, UI 容器組件不實(shí)施提供 listData 訪問(wèn)權(quán)的接口。Button 和 Label 等控制組件提供這一訪問(wèn)權(quán), 但對(duì)于容器, 您必須自己實(shí)施接口。
實(shí)施這個(gè)接口很簡(jiǎn)單, 您可以在 Flex 文檔中找到說(shuō)明。您必須為 BookItemRenderer 類執(zhí)行以下操作:
當(dāng)列表控制看到 itemRenderer 實(shí)施 IDropInListItemRenderer 接口時(shí), 它將創(chuàng)建一個(gè) listData 項(xiàng)目并將它指派到每個(gè) itemRenderer 實(shí)例。
invalidateList()
在我的類中設(shè)置這個(gè)標(biāo)準(zhǔn)并不像指派值這么簡(jiǎn)單。那樣做無(wú)法告知 Flex 框架數(shù)據(jù)已更改。標(biāo)準(zhǔn)更改必須觸發(fā)一個(gè)事件。以下是對(duì) set criteria() 函數(shù)的修改內(nèi)容:
public function set criteria( value:Number ) : void{_criteria = value;invalidateList();}注意, 一旦設(shè)置 _criteria 值, 它會(huì)調(diào)用 invalidateList()。這將使用 dataProvider 的值重置所有 itemRenderer 并調(diào)用它們的 set data 函數(shù)。
隨后的流程如下:
活動(dòng)
在之前的文章中, 我向您展示了如何借助事件冒泡使 itemRenderer 與應(yīng)用程序的其余部分通信。我認(rèn)為這相當(dāng)快。但我認(rèn)為還有更好的方法, 它符合 itemRenderer 負(fù)責(zé)展示數(shù)據(jù)、控制負(fù)責(zé)處理數(shù)據(jù)的想法。
MyTileList 控制的構(gòu)思是, 它是可售書(shū)籍目錄的可見(jiàn)視圖。當(dāng)用戶選中一本書(shū)籍并要購(gòu)買它時(shí), 列表控制應(yīng)當(dāng)將這個(gè)信息發(fā)送給應(yīng)用程序。換言之:
<CatalogList bookBuy="addToCart(event)" />
萬(wàn)事俱備, 事件冒泡并跳過(guò) MyTileList。冒泡方法沒(méi)有將事件 (bookBuy) 與列表控制 (MyTileList) 關(guān)聯(lián)在一起, 允許您將控制移到應(yīng)用程序的其他部分。例如, 如果您在主 Application 中寫(xiě)入 bookBuy 的事件偵聽(tīng)器, 您無(wú)法將列表控制移到應(yīng)用程序的其他部分。如果要移動(dòng), 您還得移動(dòng)那個(gè)事件處理函數(shù)。另一方面, 如果您將事件與控制關(guān)聯(lián)在一起, 只是移動(dòng)控制。
我們這樣看: 假設(shè) Button 上的單擊事件并不是 Button 調(diào)度的事件, 但由于按鈕中的某個(gè)內(nèi)容而冒泡。您將無(wú)法使用: <mx:Button click="doLogin()" label="Log in" />; 您必須將 doLogin() 函數(shù)放在其他位置, 這會(huì)使應(yīng)用程序更難使用。
希望我已經(jīng)說(shuō)服您, 以下是如何將這個(gè)示例從冒泡更改為從列表控制調(diào)度。
現(xiàn)在, itemRenderer 中的 Button 可以使用記錄數(shù)據(jù) (或適合此操作的其他任何內(nèi)容) 輕松調(diào)用列表控制中的函數(shù), 并將與應(yīng)用程序其余部分協(xié)調(diào)的職責(zé)轉(zhuǎn)交給列表控制。
本例中的列表控制使用數(shù)據(jù)調(diào)度事件。應(yīng)用程序可以使用 ActionScript 為這個(gè)事件添加事件偵聽(tīng)器, 也可以使用 MXML (因?yàn)?CatalogList.as 文件中的 [Event] 元數(shù)據(jù)) ; 使用 [Event] 元數(shù)據(jù)使開(kāi)發(fā)人員能更輕松地使用您的代碼。
后續(xù)工作
itemRenderer 應(yīng)使用事件進(jìn)行任何操作通信。自定事件允許您將信息隨事件傳遞, 這樣事件使用者無(wú)需再通過(guò) itemRenderer 獲取數(shù)據(jù)。
itemRenderers 應(yīng)通過(guò)覆蓋它們的 set data 函數(shù)對(duì)數(shù)據(jù)更改作出“反應(yīng)”。在該函數(shù)中, 它們可以訪問(wèn)其 listData.owner 中的值。它們還可以訪問(wèn)存儲(chǔ)在靜態(tài)類或通過(guò) Application.application 存儲(chǔ)在主應(yīng)用程序中的數(shù)據(jù)。
轉(zhuǎn)載于:https://www.cnblogs.com/hainange/archive/2009/10/17/6153064.html
總結(jié)
以上是生活随笔為你收集整理的理解Flex itemRenderer(3)--通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 72v120ah锂电池能跑多远
- 下一篇: MyEclipse优化浅析