ActionScript 2事件的最佳实践 - 是否有一种方法模拟ActionScript 3样式的事件?

8
我喜爱AS3事件模型,它有助于保持我的代码简洁且松散耦合。过去我曾经工作于AS2项目中,我的代码不够整洁,类之间的依赖性更强。由于AS2对作用域的处理很奇怪,我从未真正适应AS2事件系统。
由于我仍然偶尔需要在AS2中工作,我的问题是:
是否有人成功模拟了AS3事件API,如果没有,监听和分发事件以及处理作用域的最佳实践是什么?
3个回答

9

实际上,这很容易做到。只需要几个类就可以开始了。第一个是一个 Event 类,如下所示:

class com.rokkan.events.Event
{

    public static var ACTIVATE:String = "activate";
    public static var ADDED:String = "added";
    public static var CANCEL:String = "cancel";
    public static var CHANGE:String = "change";
    public static var CLOSE:String = "close";
    public static var COMPLETE:String = "complete";
    public static var INIT:String = "init";

    // And any other string constants you'd like to use...

    public var target;
    public var type:String;

    function Event( $target, $type:String )
    {
        target = $target;
        type = $type;
    }

    public function toString():String
    {
        return "[Event target=" + target + " type=" + type + "]";
    }
}

然后,我使用其他两个基类。一个是普通对象的基类,另一个是需要扩展MovieClip的对象的基类。首先是非MovieClip版本...

import com.rokkan.events.Event;
import mx.events.EventDispatcher;

class com.rokkan.events.Dispatcher
{

    function Dispatcher()
    {
        EventDispatcher.initialize( this );
    }

    private function dispatchEvent( $event:Event ):Void { }
    public function addEventListener( $eventType:String, $handler:Function ):Void { }
    public function removeEventListener( $eventType:String, $handler:Function ):Void { }
}

接下来是 MovieClip 版本...
import com.rokkan.events.Event;
import mx.events.EventDispatcher;

class com.rokkan.events.DispatcherMC extends MovieClip
{

    function DispatcherMC()
    {
        EventDispatcher.initialize( this );
    }

    private function dispatchEvent( $event:Event ):Void { }
    public function addEventListener( $eventType:String, $handler:Function ):Void { }
    public function removeEventListener( $eventType:String, $handler:Function ):Void { }
}

只需使用Dispatcher或DispatcherMC扩展您的对象,您就可以类似于AS3调度事件并监听事件。仅有一些小问题需要注意。例如,当您调用dispatchEvent()时,您必须传入一个引用到正在分派事件的对象,通常只需引用对象的this属性即可。

import com.rokkan.events.Dispatcher;
import com.rokkan.events.Event;

class ExampleDispatcher extends Dispatcher
{
    function ExampleDispatcher()
    {

    }

    // Call this function somewhere other than within the constructor.
    private function notifyInit():void
    {
            dispatchEvent( new Event( this, Event.INIT ) );
    }
}

另一个奇怪的地方是当你想要监听该事件时。在AS2中,您需要使用Delegate.create()来获取事件处理函数的正确作用域。例如:
import com.rokkan.events.Event;
import mx.utils.Delegate;

class ExampleListener
{
    private var dispatcher:ExampleDispatcher;

    function ExampleDispatcher()
    {
        dispatcher = new ExampleDispatcher();
        dispatcher.addEventListener( Event.INIT, Delegate.create( this, onInit );
    }

    private function onInit( event:Event ):void
    {
        // Do stuff!
    }
}

希望我从旧文件中正确复制并粘贴了所有内容!希望这对您有所帮助。


@Matt W,$符号是用来做什么的? - Simsons
@Subhen,那只是我曾经使用的旧代码风格约定,用于区分函数参数和本地变量以及实例变量。 - Matt W

2

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接