【问题标题】:Generic events and additional parameters in Actionscript 3.0?Actionscript 3.0 中的通用事件和附加参数?
【发布时间】:2009-09-16 06:13:29
【问题描述】:

假设以下模式:

someObjectInstance.addEventListener(MyDisplayObject.EVENT_CONSTANT, _handleMyEvent);


private function _handleMyEvent( event:Event = null ):void
{
  // Event handler logic...
}

如果我想向处理函数添加一个必需的参数,我是否能够这样做并且仍然使用“通用”事件和事件侦听器?或者我是否正确假设我需要创建一个包含参数的自定义事件类并通过传递给处理函数的事件对象引用它?

换一种说法......如果我有一个看起来像这样的处理函数:

private function _handleMyEvent( data:Object, event:Event = null ):void
{
  if (data == null)
  {
      return;
  }
  // Event handler logic...
}

那么 addEventListener 函数需要是什么样子的呢?有没有更高级的语法?有没有办法用闭包做到这一点?

寻找清晰的代码示例和/或文档参考。只是想了解在这种情况下我是否必须重写通用 Event 类。

【问题讨论】:

    标签: actionscript-3 events


    【解决方案1】:

    如果您需要自定义数据来与您的活动一起旅行,是的,您需要创建一个自定义事件类。

    这是一个简单的例子:

    package {
        import flash.events.Event;
    
        public class ColorEvent extends Event {
            public static const CHANGE_COLOR:String = "ChangeColorEvent";
    
            public var color:uint;
    
            public function ColorEvent(type:String, color:uint, bubbles:Boolean = false, cancelable:Boolean = false) {
                this.color = color;
                super(type, bubbles, cancelable);
            }
    
            override public function clone():Event {
                return new ColorEvent(type, color, bubbles, cancelable);
            }
        }
    }
    

    请注意,克隆方法不是可选的。您必须在自定义类中使用此方法,才能正确地重新广播您的事件(例如,当一个对象获得该事件,然后将其重新分派为它自己的)。

    现在至于调度事件,它会像这样工作(显然这段代码将进入扩展 EventDispatcher 的类的方法中)。

    dispatchEvent(new ColorEvent(ColorEvent.CHANGE_COLOR, 0xFF0000));
    

    最后,订阅事件:

    function onChangeColor(event:ColorEvent):void {
        trace(event.color);
    }
    
    foo.addEventListener(ColorEvent.CHANGE_COLOR, onChangeColor);
    

    【讨论】:

    • 在我的例子中,我创建了一个自定义事件类,它可以接受一组参数,如果我想让它独一无二,只需自定义事件名称。从长远来看,我实际上发现最小的、更通用的事件名称比特定的更容易维护。由于处理事件的对象通常为您提供足够的上下文来理解代码,因此减少了头痛。但没有错误的答案。只是风格偏好。
    • 指出重写 clone() 方法不是可选的,这节省了我的时间,文档中没有正确解释。非常感谢!
    【解决方案2】:

    有一种方法可以将自定义数据传递给处理程序方法,而无需创建自定义事件。

    private function test() {
        var data : SomeObject = new SomeObject;
        var a:SomeEventDispatcher = new SomeEventDispatcher();
        a.addEventListener(Event.COMPLETE, handle(data));   
        a.dispatchCompleteEvent();
    }
    
    private function handle(data : SomeObject) : Function {
        return function(e : Event) : void {
           IEventDispatcher(e.target).removeEventListener(Event.COMPLETE, arguments.callee);
           trace(e + ", " + data);
        };
    }
    

    【讨论】:

      【解决方案3】:

      请等一下,各位。见this answer

      您根本不需要自定义任何东西来通过侦听器引用参数。所以,是的,Gordon,你可以用你的普通事件和事件监听器来做到这一点。

      而且很简单! addEventListener 函数保持不变。它的监听器将被调整:

      var functionHandleMyEvent:Function = _handleMyEvent(data);
      someObjectInstance.addEventListener(MyDisplayObject.EVENT_CONSTANT, functionHandleMyEvent);
      // Later, when you need to remove it, do:
      //someObjectInstance.removeEventListener(MyDisplayObject.EVENT_CONSTANT, functionHandleMyEvent);
      
      private function _handleMyEvent(data:Object):Function {
        return function(event:Event):void {
          if (data == null) {
            // Event handler logic here now has both "event" and "data" within your reach
          }
        }
      }
      

      没有高级语法,而是一个相对高级的概念:variable functions。你可以用我们这里的东西来做闭包,但你绝对不需要。这样,您也绝对不需要重写 Event 类。

      我希望这些示例和文档对您有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-13
        • 1970-01-01
        • 2012-12-24
        • 2017-06-08
        • 1970-01-01
        相关资源
        最近更新 更多