什么是在AS3中调度事件时的适当形式?

时间:2011-06-23 04:01:27

标签: actionscript-3 events coding-style event-dispatching

我想知道创建自定义事件时适当的表单是什么?应该创建一个CustomEvent类,然后在函数中创建一个临时调度程序,并调度CustomEvent。或者更好的方法是尝试创建一个CustomEventDispatcher类,并将CustomEvent类创建为该类的内部类,例如:

package
{

   public class CustomEventDispatcher extends EventDispatcher
   {
     public function CustomEventDispatcher()
     {
       super(new CustomEvent());
     }

   }
}

class CustomEvent
{
   public function CustomEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
   {
      super(type, bubbles, cancelable)
   }                                               
}

3 个答案:

答案 0 :(得分:2)

单方面,最好将事件公开访问。通过这种方式,您可以键入侦听器(适用于代码提示和调试),并使Event具有公共静态const类型(您也可能希望查看)。

答案 1 :(得分:0)

不要忘记覆盖克隆。覆盖toString进行调试也是一个好主意。

这是我的一个自定义事件的示例:

package com.mattie.events
{
//Imports
import flash.events.Event;

//Class
public class SearchFieldEvent extends Event
    {
    //Constants
    public static const SEARCH_COMPLETE:String = "search complete";

    //Variables
    public var totalResults:uint;
    public var duration:uint;
    public var searchText:String;

    //Constructor
    public function SearchFieldEvent(type:String, totalResults:uint = 0, duration:uint = 0, searchText:String = "") 
        {
        super(type);

        this.totalResults = totalResults;
        this.duration = duration;
        this.searchText = searchText;
        }

    //Override clone
    public override function clone():Event
        {
        return new SearchFieldEvent(type, totalResults, duration, searchText);
        }

    //Override toString
    public override function toString():String
        {
        return formatToString("SearchFieldEvent", "type", "totalResults", "duration", "searchText");
        }
    }
}

答案 2 :(得分:0)

在构思事件机制时,有两个基本问题需要回答。

1)如何为我的活动创建调度程序实例?

常规选项包括:扩展EventDispatcher或聚合调度程序实例。

大多数基本和常见的做法(以及官方文档也说明),正在扩展EventDispatcher类,从而为您的类提供事件派发功能。

优点:易于实现 - 只需输入extends EventDispatcher,即可完成。

缺点:您无法扩展其他内容。显然,这就是为什么许多本地类都是EventDispatcher的孙子的原因。我想,只是为了免除我们的麻烦。

第二种通用​​方法是聚合调度程序实例。

package
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;

    public class ClassA implements IEventDispatcher
    {
        private var dispatcher:EventDispatcher;

        public function ClassA()
        {
            initialize();
        }

        private function initialize():void
        {
            dispatcher = new EventDispatcher(this);
        }

        public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
        {
            dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
        }

        public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
        {
            dispatcher.removeEventListener(type, listener, useCapture);
        }

        public function dispatchEvent(event:Event):Boolean
        {
            return dispatcher.dispatchEvent(event);
        }

        public function hasEventListener(type:String):Boolean
        {
            return dispatcher.hasEventListener(type);
        }

        public function willTrigger(type:String):Boolean
        {
            return dispatcher.willTrigger(type);
        }
    }
}

注意:我们将聚合类的引用传递给调度程序构造函数。 这样做是为了使event.target引用您的类实例而不是调度程序实例本身。

优点:您可以自由扩展任何您喜欢的内容。您可以使用调度程序挂钩来做一些技巧,例如维护侦听器列表或类似的东西。

缺点:不像第一种方法那么简单。

2)如何通过我的活动传递自定义数据?

常规选项包括:在事件实例中传递数据,或仅在事件处理程序中使用event.target引用来从源访问某些数据。

如果您选择通过event.target访问所有必要的数据 - 没有额外的工作,只需将事件处理程序中的此引用转换为适当的类。

如果你想传递一些数据和事件,你就是子类Event,这个类应该对处理事件的代码公开可见,如上面的答案所述。 AS3是关于严格和强大的打字,所以为什么你会拒绝?

只有在要重新调度已处理事件时,才需要覆盖Event子类中的clone()方法。官方文档说,每次创建自定义事件类时都必须这样做,只是为了安全。