[转]FLEX2 mx.events.EventDispatcher的分析-- 典型的观察者实现

[url]http://blog.youkuaiyun.com/sshcx/archive/2005/10/16/504932.aspx[/url]
类的路径: classes/mx/events/EventDispatcher.as 这个类所有的属性和方法都是静态的。这说明,我们不必要实例化一个EventDispatcher,实例化也没有意义。
这个类有一个属性:


fEventDispatcher


(static var _fEventDispatcher:EventDispatcher = undefined;)


它是这个类在内部的实例,作用是可以向别的对象添加方法。
我们在外部用到的这个类的方法有这么几个:


initialize(object:Object):Void
dispatchEvent(eventObj:Object):Void
addEventListener(event:String, handler):Void
removeEventListener(event:String, handler):Void


这是flash MX的ASBroadcaster有点儿相似, 事实上实现方法也有点儿相似。只是ASBroadcaster还有一些bug。在flashcoder wiki里面有相关的资料。


Dispatcher的例子:


import mx.events.EventDispatcher;


// 产生国王


King = new Object();


// 初始化国王为驱使者


EventDispatcher.initialize(King);


subject = {}; // 产生奴仆
// 把它加到国王的被驱使者,


King.addEventListener("onKingScream", subject);


// 告诉我们的奴仆,他应该做的事


subject.onKingScream = function() {
trace("带葡萄过来!");
}


// 这里我们让国王高吼两次, 用来加强语气,:)


// dispatchEvent方法是广播出去事件,在这里的事件类型是 “onKingScream”
King.dispatchEvent({type:"onKingScream"});
King.dispatchEvent({type:"onKingScream"});


函数一:
static function initialize(object:Object):Void {
if (_fEventDispatcher == undefined) {
_fEventDispatcher = new EventDispatcher;
}
object.addEventListener = _fEventDispatcher.addEventListener;
object.removeEventListener = _fEventDispatcher.removeEventListener;
object.dispatchEvent = _fEventDispatcher.dispatchEvent;
object.dispatchQueue = _fEventDispatcher.dispatchQueue;
}
用类的静态属性_fEventDispatcher的方法来传递给object。这就是刚才提到的这个属性的作用。这样的话, 我们可以使用object.addEventListener()、object.removeEventListener()、object.dispatchEvent()这三个方法。上面的例子中就用到了其中的两个方法。

函数二:


function addEventListener(event:String, handler):Void {
var queueName:String = "__q_"+event;
if (this[queueName] == undefined) {
this[queueName] = new Array();
}
_global.ASSetPropFlags(this, queueName, 1);
EventDispatcher._removeEventListener(this[queueName], event, handler);
this[queueName].push(handler);
}
这就表明每一种事件都存在一个数组EventDispatcher[“__q_onKingScream”]中,
而数组的里面存储的数据则是事件侦听器的引用。
像国王的那个例子,假如是
for(var i:Number=0;i<5;i++) {
King.addEventListener(“onKingScream”,listenObj[i]);
}
假设这段代码前,listenObj[i]就已经定义了。那么就成了一个这样的数组:
EventDispatcher[“__q_onKingScream”]

函数三:
function removeEventListener(event:String, handler):Void {
var queueName:String = "__q_" + event;
EventDispatcher._removeEventListener(this[queueName], event, handler);
}
调用内部函数_removeEventListener(),传递参数第一个就是刚才提到的那个数组。 函数四:
static function _removeEventListener(queue:Object, event:String, handler):Void {
if (queue != undefined) {
var l:Number = queue.length;
var i:Number;
for (i = 0; i < l; i++) {
var o = queue[i];
if (o == handler) {
queue.splice(i, 1);
return;
}
}
}
}
这是一个比较重要的函数,它实现删除一个事件的侦听器,其实是删除引用。假如数组里面有一个侦听器的引用跟handler相同,那么就从数组中删除。 函数五:


function dispatchEvent(eventObj:Object):Void {


if (eventObj.target == undefined) {


eventObj.target = this;


}


this[eventObj.type+"Handler"](eventObj);


// Dispatch to objects that are registered as listeners for


// this object.


this.dispatchQueue(this, eventObj);


}
这个函数就是我们派发事件的函数了。假如你用了类似enventNameHandler的方法,比如说clickHandler,(a)就会帮你实现这个方法。后面就调用了dispatchQueue()函数, 这才是我们dispatch事件实现的真正函数, 是一个内部的函数。我们这里传了this参数过去,也就是EventDispatcher的引用。

函数五:


function dispatchQueue(queueObj:Object, eventObj:Object):Void {


var queueName:String = "__q_"+eventObj.type;


var queue:Array = queueObj[queueName];


if (queue != undefined) {


var i:String;


// loop it as an object so it resists people removing listeners during


// dispatching


for (i in queue) {


var o = queue[i];


var oType:String = typeof (o);


// a handler can be a function, object, or movieclip


if (oType == "object" || oType == "movieclip") {


// this is a backdoor implementation that


// is not compliant with the standard


if (o.handleEvent == undefined) {


o[eventObj.type](eventObj); (b);


} else {


// this is the DOM3 way


o.handleEvent(eventObj); (c);


}


} else {


// it is a function


o.apply(queueObj, [eventObj]); (d);


}


}


}


}


派发事件了,(b)就是指handleEvent方法。国王的那个例子就是这用这个函数实现的。
(c)就是DOM3的标准方式
myObj.handleEvent = function(o){
if (o.type == "click"){
// your code here
} else if (o.type == "enter"){
// your code here
}
}
不是很方便。
(d)指传递了函数o,这样的话o.appy()就可以实现这个函数的调用。
突然发现有一个地方有错误,昨晚因为太赶,所以没注意。
this不是指EventDispatecher类的引用,而是initialize()函数定义的那个派发对象object的引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值