理解Flex itemRenderer(3)--通信
在本系列的第 2 部分中, 我向您展示了如何使用 MXML 和 ActionScript 創建外部 itemRenderer。在我用過的示例中, 有一個調度自定事件 BuyBookEvent 的 Button-這樣應用程序可以對它作出響應。本文進一步討論與 itemRenderer 的通信。
我堅信有一條規則是永遠不能違背的: 不能抓住 itemRenderer 的實例不放, 更改它 (設置公共屬性) 或調用它的公共方法。這對我而言是一個禁忌。itemRenderer 是很難弄清的, 我在第 1 部分中說到了其中的緣由: itemRenderer 是循環使用的。抓住一個會破壞 Flex 框架。
請將這條規則謹記在心, 您可以使用 itemRenderer 完成以下操作:
- itemRenderer 可以通過它的列表所有者調度事件。 (您已經看到過冒泡; 這個做法更好, 接下來您就會看到。)
- itemRenderer 可以使用靜態類成員。其中包括 Application.application。如果您的值“全局”存儲在應用程序對象中, 您可以通過這種方式獲得它們。
- itemRenderer 可以使用擁有它的列表的公共成員。接下來您就會看到。
- itemRenderer 可以使用數據記錄中的任何內容。例如, 記錄中的某個項目不用于直接顯示, 但它卻影響 itemRenderer 的行為方式。
動態更改 itemRenderer
以下是上一篇文章中用于 TileList 的 MXML itemRenderer。我將使它對外部源 (我將這個文件稱為 BookItemRenderer.mxml) 的更改作出反應, 從而使它更生動:
<?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>假設您在 TileList 中顯示一個商品目錄。您還有一個 Slider (不屬于 itemRenderer), 它允許用戶給出一個價格范圍; 在此范圍之外的所有商品應變灰 (itemRenderer 的 alpha 值應改變)。您需要告知所有 itemRenderer 標準已改變, 這樣它們可以修改自己的 alpha 值。
覆蓋 set data 可能如下:
override public function set data( value:Object ) : void {super.data = value;if( data.price < criteria ) alpha = 0.4;else alpha = 1; }問題是: 如何更改標準值?itemRenderer 的“最佳做法”是始終讓它們處理為自己手頭的數據。在本例中, 將測試標準作為數據的一部分不可能也不切實際。所以這在數據外留下了一個位置。您有兩個選擇:
- 列表本身的一部分。即, 您的列表 (List、DataGrid、TileList 或其他) 可以是擴展列表控制并且將這個標準作為公共成員的類。
- 作為全局數據的應用程序的一部分。
我選擇第一個: 擴展一個類并將這個標準作為該類的一部分。畢竟, 這個類將用于顯示數據, 而標準是顯示內容的一部分。對于本例, 我將擴展 TileList 并將標準作為公共數據成員。
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;} } }這個辦法是, itemRenderer 外的控制可以通過更改列表控制上的這個屬性來修改標準。
listData
itemRenderer 可以訪問另一塊數據: 列表本身的相關信息以及它們渲染哪個行哪個列 (如果在面向列的控制中)。這稱為 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; }將這個代碼放入上述示例 BooktItemRenderer.mxml 代碼的 <mx:Script> 塊中。
itemRenderer 的 listData property 有一個 owner 字段, 它是 itemRenderer 所屬的控制。在本例中, 所有者是 MyTileList 控制-我的 TileList 擴展。將所有者字段轉換為 MyTileList 即可取走標準。
IDropInListItemRenderer
當 itemRenderer 類實施 IDropInListItemRenderer 接口時, 即可訪問 listData。不幸的是, UI 容器組件不實施提供 listData 訪問權的接口。Button 和 Label 等控制組件提供這一訪問權, 但對于容器, 您必須自己實施接口。
實施這個接口很簡單, 您可以在 Flex 文檔中找到說明。您必須為 BookItemRenderer 類執行以下操作:
當列表控制看到 itemRenderer 實施 IDropInListItemRenderer 接口時, 它將創建一個 listData 項目并將它指派到每個 itemRenderer 實例。
invalidateList()
在我的類中設置這個標準并不像指派值這么簡單。那樣做無法告知 Flex 框架數據已更改。標準更改必須觸發一個事件。以下是對 set criteria() 函數的修改內容:
public function set criteria( value:Number ) : void{_criteria = value;invalidateList();}注意, 一旦設置 _criteria 值, 它會調用 invalidateList()。這將使用 dataProvider 的值重置所有 itemRenderer 并調用它們的 set data 函數。
隨后的流程如下:
活動
在之前的文章中, 我向您展示了如何借助事件冒泡使 itemRenderer 與應用程序的其余部分通信。我認為這相當快。但我認為還有更好的方法, 它符合 itemRenderer 負責展示數據、控制負責處理數據的想法。
MyTileList 控制的構思是, 它是可售書籍目錄的可見視圖。當用戶選中一本書籍并要購買它時, 列表控制應當將這個信息發送給應用程序。換言之:
<CatalogList bookBuy="addToCart(event)" />
萬事俱備, 事件冒泡并跳過 MyTileList。冒泡方法沒有將事件 (bookBuy) 與列表控制 (MyTileList) 關聯在一起, 允許您將控制移到應用程序的其他部分。例如, 如果您在主 Application 中寫入 bookBuy 的事件偵聽器, 您無法將列表控制移到應用程序的其他部分。如果要移動, 您還得移動那個事件處理函數。另一方面, 如果您將事件與控制關聯在一起, 只是移動控制。
我們這樣看: 假設 Button 上的單擊事件并不是 Button 調度的事件, 但由于按鈕中的某個內容而冒泡。您將無法使用: <mx:Button click="doLogin()" label="Log in" />; 您必須將 doLogin() 函數放在其他位置, 這會使應用程序更難使用。
希望我已經說服您, 以下是如何將這個示例從冒泡更改為從列表控制調度。
現在, itemRenderer 中的 Button 可以使用記錄數據 (或適合此操作的其他任何內容) 輕松調用列表控制中的函數, 并將與應用程序其余部分協調的職責轉交給列表控制。
本例中的列表控制使用數據調度事件。應用程序可以使用 ActionScript 為這個事件添加事件偵聽器, 也可以使用 MXML (因為 CatalogList.as 文件中的 [Event] 元數據) ; 使用 [Event] 元數據使開發人員能更輕松地使用您的代碼。
后續工作
itemRenderer 應使用事件進行任何操作通信。自定事件允許您將信息隨事件傳遞, 這樣事件使用者無需再通過 itemRenderer 獲取數據。
itemRenderers 應通過覆蓋它們的 set data 函數對數據更改作出“反應”。在該函數中, 它們可以訪問其 listData.owner 中的值。它們還可以訪問存儲在靜態類或通過 Application.application 存儲在主應用程序中的數據。
轉載于:https://www.cnblogs.com/hainange/archive/2009/10/17/6153064.html
總結
以上是生活随笔為你收集整理的理解Flex itemRenderer(3)--通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 72v120ah锂电池能跑多远
- 下一篇: 路虎发现运动版二手车值得买吗