標籤雲

搜尋此網誌

2009/09/23

ActionScript 3.0 的事件模型

(於 200909 整理舊文後重寫)

Flash 的事件模型中有幾種角色:
1. 事件發出者 -- 負責發出事件及傳遞事件實體
(1) 自定義的類別要成為事件發出者最簡單的方式,就是 extends EventDispatcher。因為事件發出的方法 dispatchEvent,就定義在 EventDispatcher 裡面
(2) 如果此類別已經擴充其它類別,可以改為實作 IEventDispatcher 介面、建立 EventDispatcher 成員,然後撰寫簡單的攔截程序將呼叫遞送到彙總的 EventDispatcher。
(3) 事實上, EventDispatcher 是一個很上層的類別, 所以子系類別很多, 舉凡 SimpleButton, Sprite 等等都是。

2. 事件實體 -- 事件的常數字串會定義在這邊,實體是被事件發出者產生
(1) 最簡單最上層的就是 Event 類別,可以繼承他然後自己寫出自定義的事件實體。你可以自定義事件的建構子參數中定義任何你想傳遞給監聽者的資料
(2) 建立自定義事件時,必須覆寫 Event.clone() 方法,才能讓其複製自訂的屬性。否則這些屬性將無法在偵聽程式處理重新傳送的事件時,提供正確的值。

3. 監聽者 -- 負責接收事件實體並處理事件
透過事件實體,監聽者可以完全不管事件發出者的屬性跟方法。只要利用 addEventListener(事件類別.事件常數, 事件處理函式) 的方法針對事件去監聽並指派處理函式,來完成事件的處理即可。


來看看簡單的範例吧

事件實體:
package edlo.events{
//import
import flash.events.Event;

public class DataInsideEvent extends Event{
/* ======= Event const ============================== */
public static const DATA_INSIDE:String = "dataInside"; //自定義的事件常數

/* ======= attributes =============================== */
private var _data:Object;

/* ===============================================
* constructor
* =============================================== */
public function DataInsideEvent(type:String, data:Object=null, bubbles:Boolean = false, cancelable:Boolean = false):void{
super(type, bubbles, cancelable);
this._data = data;
}
/* ===============================================
* functions
* =============================================== */
public override function clone():Event{
return new DataInsideEvent(type, this._data, bubbles, cancelable);
}
/* ===============================================
* Setter & Getter
* =============================================== */
public function get data():Object{
return this._data;
}
}
}

事件發出者:
...(略)
//在類別宣告前用後設標籤宣告此類別會發出什麼事件
[Event(name=DataInsideEvent.DATA_INSIDE, type="DataInsideEvent")]
....(略)
//這邊的例子是本身的MouseEvent.CLICK事件觸發後,發出一個自定義的事件給外面
private function onItemClick(e:MouseEvent):void {
dispatchEvent(new DataInsideEvent("dataInside", {itemName: e.currentTarget.name}));
}
...(略)

事件監聽者:
...(略)
content.addEventListener(DataInsideEvent.DATA_INSIDE, onMenuItemClick);
...(略)
private function onMenuItemClick(e:DataInsideEvent):void {
trace(DataInsideEvent.data. itemName);
}

如果不需傳遞什麼參數的話...可以用 Event 類別作為事件實體....這樣就不必專門寫一個事件實體出來
再偷懶一點的話可以一個類別自己發出事件自己監聽
看情況提供作為參考嚕

以上
只要可以搞懂 AS 3 事件模型的概念
相信對於整個 ActionScript 的了解程度上面會更進一步
開發時在架構規劃上也是會很有幫助的

沒有留言: