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

http://blog.csdn.net/sshcx/archive/2005/10/16/504932.aspx
类的路径: 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的引用。

你可能感兴趣的:(.net,Blog,Flash)