上一篇主要以代碼的方式說明了如何使用自訂事件在父子組件之間傳遞資料,那麼在開發中,我們可能會遇到另一種情況,就是想在任意一個地方監聽到任意一個組件中被觸發的事件,這樣事件處理更靈活,並不局限於父子組件之間,那麼下面就說明這種情況如何處理。
Flex中所有的組件都間接繼承自EventDispatcher,通過查看Flex API,瞭解一下這個類中的方法。
所見,該類包含了派發事件、監聽事件、移出事件等方法,那麼通過這個類就可以實現本文開篇所提出的那種情況,分析一下,監聽事件的對象和派發事件的對象必須是同一個對象,這樣事件才能被捕獲,所以我們需要寫一個單例的類,並且組合EventDispatcher,可以滿足需求。
events/MyEventDispatcher.as,這裡同樣不建議以My起頭命名,只是測試用。
package events{import events.MyEvent;import flash.events.Event;import flash.events.EventDispatcher;import flash.events.IEventDispatcher;import mx.core.Singleton;public class MyEventDispatcher{private static var _inst:MyEventDispatcher;private var eventDispatcher:IEventDispatcher;public function MyEventDispatcher(singleton:Singleton){if(singleton == null){throw new Error("Create MyEventDispatcher Error!");}eventDispatcher = new EventDispatcher();}public static function getInstance():MyEventDispatcher{if (!_inst){_inst = new MyEventDispatcher(new Singleton);}return _inst;}public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, pririty:int=0, useWeakReference:Boolean=true):void{eventDispatcher.addEventListener(type, listener, useCapture, pririty, useWeakReference);}public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=true):void{eventDispatcher.removeEventListener(type, listener, useCapture);}public function dispatchEvent(event:MyEvent):Boolean{return eventDispatcher.dispatchEvent(event);}public function hasEventListener(type:String):Boolean{return eventDispatcher.hasEventListener(type);}public function willTrigger(type:String):Boolean{return eventDispatcher.willTrigger(type);}}}class Singleton {} 為了節省空間的,類裡不加註釋了,其實也不要緊,功能很簡單,組合了EventDispatcher對象,對其做了一層代理,並且對MyEventDispatcher單例話,為什麼採用單例上面已經說過了,但是為什麼使用組合而不是繼承呢,在OOPS(物件導向程式設計系統)中,有一條原則是優先使用組合而非繼承,組合比繼承更靈活,組合允許在運行期間通過設定類的屬性來改變類的行為,並且可以使用介面來組合一個類,提供了更高的靈活性。 到目前為止,我們的工作已經完成一大半了,在上一篇中設計了一個自訂事件類別,也就是events/MyEvent.as,我們可以在該類中加入一個dispatch方法,建立完事件之後可以派發,代碼如下:
/** * 派發事件 * @return */public function dispatch():Boolean{ return MyEventDispatcher.getInstance().dispatchEvent(this);} 這樣,建立完自訂事件之後,就可以直接派發事件了,那麼使用起來就很方便了,下面是具體使用代碼,一個應用中有兩個自訂群組件,組件一中有個TextArea,組件二中有個按鈕,點擊按鈕,將資料傳遞到TextArea中。 EventTest.mxml
<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:components="components.*"><s:layout><s:VerticalLayout/></s:layout><components:component1 /><components:component2 /></s:Application>
components/component1.mxml
<?xml version="1.0" encoding="utf-8"?><s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="creationCompleteHandler(event)"><fx:Script><![CDATA[import events.MyEventDispatcher;import events.MyEvent;import mx.events.FlexEvent;protected function creationCompleteHandler(event:FlexEvent):void{MyEventDispatcher.getInstance().addEventListener(MyEvent.SHOWINFO, showInfo);}protected function showInfo(event:MyEvent):void{textArea.text = event.data;}]]></fx:Script><s:TextArea id="textArea" /></s:Group>
components/component2.mxml
<?xml version="1.0" encoding="utf-8"?><s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"><fx:Script><![CDATA[import events.MyEvent;import events.MyEventDispatcher;protected function buttonClickHandler(event:MouseEvent):void{var myEvent:MyEvent = new MyEvent(MyEvent.SHOWINFO);myEvent.data = "哈哈";myEvent.dispatch();}]]></fx:Script><s:Button label="顯示內容" click="buttonClickHandler(event)"/></s:Group>
好,這樣就實現了在任意一個地方監聽到任意一個組件中被觸發的事件的功能,文中如有錯誤之處,歡迎指出,大家共同進步。
本文來自:高爽|Java And Flex Corder,原文地址:http://blog.csdn.net/ghsau/article/details/7396614。