AS3.0教程(10):强大的事件机制(6) 占个座位先
Author: 柳世杀神·GabrielGon
18
十一
2006
| AS3.0教程(10):强大的事件机制(6) |
来源: http://www.kingda.org/archives/kingda/2006/08/as30106.html#more
作者:黑羽(KingdaSun)
事件机制写的太多了,我自己都有点烦了。 但没办法,太重要了。而且AS3做了这么多好的改进,值得我们去一一探寻,给我们日后的编程带来极大的便利。Actionscript 初学者,本节可以跳过不看。 Actionscript 2熟练工应当看看,有些价值。
今儿讲掉 4. 合成EventDispatcher进行事件发送。 5. 实现IEventDispatcher接口来进行事件发送。 与设计模式中的装饰器模式相似。 这样事件的发送和接受,就可以讲完了。
那么,事件部分就这样完了?没有!你晕,我也同晕。因为还有一个很重要的特性,Event flow机制还没讲。这就是我所说的事件冒泡机制。给我们编程带来了莫大的方便。
好,下面先讲:
4. 合成EventDispatcher进行事件发送。 什么情况下用合成EventDispatcher来发送Event呢? 一般发生在某个较复杂的类里面。 这个类可能是因为本身已经继承了其它类,无法再继承EventDispatcher。 如果仅仅是因为这个原因,那么我更加建议使用 实现IEventDispatcher接口来进行事件发送。 但如果原因不止如此,比如,我们不愿意这个类不是一个单纯事件发送类,而是在执行某个方法(method),比如doSomething()时,附带的发送一些事件。 这些事件发送者往往是这个类的组成部分,一些更小的类,通常是Sprite等。 那么用这种做法就比较合理。
看代码例子 //以下为一个名叫KingdaSampleClass的Document Class,请自行和一个Fla绑定。
package { import flash.display.Sprite; import flash.events.Event; import flash.events.EventDispatcher;
public class LearnCompositeEvents extends Sprite { public function LearnCompositeEvents() { var kingdaObj:KingdaClass = new KingdaClass(); //一定要用kingdaObj.getSender()来返回事件发送对象,才能addEventListener kingdaObj.getSender().addEventListener(KingdaClass.ACTION, lisFunc); kingdaObj.doSomething(); //输出: //doSomething //listened:yeahyeah } //侦听器 private function lisFunc(evtObj:Event):void { trace ("listened:"+evtObj.type); } } import flash.events.EventDispatcher; import flash.events.Event; class KingdaClass extends EventDispatcher { public var _dispatcher:EventDispatcher; public static const ACTION:String = "yeahyeah"; public function KingdaClass() { initSender(); } private function initSender():void { _dispatcher = new EventDispatcher(); } //调用一个专门的方法(method)来返回发送事件的EventDispatcher。 public function getSender():EventDispatcher { return _dispatcher; } public function doSomething():void { trace("doSomething"); //除了以下两行发送事件,还可以写入其它你要干的事儿。灵活。 var evtObj:Event = new Event(KingdaClass.ACTION); _dispatcher.dispatchEvent(evtObj); } } } |
5.实现IEventDispatcher接口来进行事件发送。 在哪种情况下使用? 类可能是因为本身已经继承了其它类,无法再继承EventDispatcher。 而我们恰恰希望它能实现EventDispatcher类所有功能,比如说addEventListener, hasListener等等,看起来简直和继承EventDispatcher没什么分别。 那么OK,我建议使用 实现IEventDispatcher接口来进行事件发送。 其实质是一个装饰器模式(Decorator),以对客户端透明的方式扩展对象功能,是继承关系的一个替代方案。其关键在于扩展是完全透明的,使用起来和继承父类几乎没什么区别。
具体方法 由于IEventDispatcher需要实现5个接口,addEventListener, hasListener, willTrigger,removeEventListener,hasEventListener,那么我们的装饰类也必须实现这五个接口。 其余看代码
优点: 1.类的用户完全感觉不到差别 2.在被包装的方法中还可以加入其它自己希望加进去的动作,比如,在addEventListenr方法中可以再插入一个计数,看看到底被add了多少次,超过某些次后,调用某个方法等等。 总而言之,给我们带来了极大的灵活性。这就是装饰器模式的好处。
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.EventDispatcher;
public class LearnDecoratorEvents extends Sprite { public function LearnDecoratorEvents() { var kingdaObj:KingdaClass = new KingdaClass(); kingdaObj.addEventListener(KingdaClass.ACTION, lisFunc); //用起来和EventDispatcher对象一样哦,呵呵。 var evtObj:Event = new Event(KingdaClass.ACTION); kingdaObj.dispatchEvent(evtObj);//确实一样吧 //输出:listened:yeahyeah } private function lisFunc(evtObj:Event):void { trace ("listened:"+evtObj.type); } } import flash.events.IEventDispatcher; import flash.events.EventDispatcher; import flash.events.Event; class KingdaClass implements IEventDispatcher{ public var _dispatcher:EventDispatcher; public static const ACTION:String = "yeahyeah"; public function KingdaClass() { // other …. initSender(); } private function initSender():void { _dispatcher = new EventDispatcher(this); } //哈哈,在实现接口时还可以乘机干点别的,比如我喜欢吧useWeakReference设为true public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void{ // do other things; _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); }
public function dispatchEvent(evt:Event):Boolean{ // do other things; return _dispatcher.dispatchEvent(evt); }
public function hasEventListener(type:String):Boolean{ // do other things; return _dispatcher.hasEventListener(type); }
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{ // do other things; _dispatcher.removeEventListener(type, listener, useCapture); }
public function willTrigger(type:String):Boolean { // do other things; return _dispatcher.willTrigger(type); } } } |
|
最活跃用户