【问题标题】:AS3 Event Bubbling outside of the Scenegraph/DisplayList场景图形/显示列表之外的 AS3 事件冒泡
【发布时间】:2009-03-19 13:52:11
【问题描述】:

您好,我想知道是否可以在 AS3 的非显示列表类中利用事件冒泡。

例如,在一个应用程序模型中,有一个包含许多汽车的 City 类。有哪些方法可以将事件侦听器附加到 City 对象并接收从子 Cars 冒出的事件。为了澄清 City 和 Car 对象不是显示列表的一部分,它们不是 DisplayObjects。那么冒泡可以以某种方式在显示列表之外实现吗?

据我所知,如果不手动将事件侦听器附加到每个 Car 对象并从 City 对象重新调度事件,这是不可能的。其他人有更清洁的解决方案吗?

【问题讨论】:

    标签: actionscript-3 events event-bubbling


    【解决方案1】:

    这门课是我解决这个问题的方法。基本上让你的类通常会扩展 EventDispatcher 而不是扩展 BubblingEventDispatcher

    然后调用 addChildTarget(target:BubblingEventDispatcher) 函数来设置子节点,您可以从中捕获冒泡事件。

    此解决方案为每个事件调度程序使用一个 sprite,但导致每个类仅使用 1 个字节的额外内存

    package 
    {
     import flash.display.Sprite;
     import flash.events.Event;
     import flash.events.EventDispatcher;
    
     public class BubblingEventDispatcher extends EventDispatcher
     {
      //We have to use a sprite to take advantage of flash's internal event bubbling system
      private var sprite:Sprite;
    
      public function BubblingEventDispatcher()
      {
       //initialize our sprite
       sprite = new Sprite();
      }
    
      public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
      {
       sprite.addEventListener( type, listener, useCapture, priority, useWeakReference );
      }
    
      public override function dispatchEvent(event:Event):Boolean
      {
       return sprite.dispatchEvent( event );
      }
    
      //We must add child targets if we want to take advantage of the bubbling
      public function addChildTarget( target:BubblingEventDispatcher ):void
      {
       sprite.addChild( target.eventTarget as Sprite );
      }
    
      public function get eventTarget():EventDispatcher
      {
       return sprite;
      }
     }
    }
    

    【讨论】:

    • 感谢您的回复。我现在正试图转移到 as3-signals,他们也有一个冒泡的解决方案。这看起来像是为原生事件完成了工作。干得好;)
    【解决方案2】:

    我不确定我是否完全理解,但是当你创建一个事件时,你可以说它会冒泡,所以当它调度时它会冒泡。

    http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html

    http://livedocs.adobe.com/flex/3/langref/flash/events/Event.html#Event()

    我相信这将允许您将事件侦听器附加到您的城市以获取正确类型的事件,并且可以捕获汽车引发的事件。我从来没有试过这个,所以我不确定。

    更新:

    啊,我没有意识到这一点。你是对的。来自以下链接:

    http://livedocs.adobe.com/flex/3/html/help.html?content=events_08.html

    当事件对象在显示列表中从一个节点移动到另一个节点时,会发生捕获和冒泡:父到子用于捕获,子到父用于冒泡。这个过程与继承层次无关。除了定位阶段之外,只有 DisplayObject 对象(容器和控件等可视对象)可以具有捕获阶段和冒泡阶段。

    我能看到的唯一方法是每次将新的孩子添加为孩子时,您都要向父母(城市的汽车)注册孩子。此时,您可以在父级(城市)中添加一个事件侦听器,然后在任何时候从子级(汽车)处理事件时从父级(城市)重新调度事件。我知道它很难看,并且您希望确保在删除孩子的任何时候都删除事件侦听器,但这是我能看到的唯一真正的解决方案。

    【讨论】:

    • 它会冒泡,但只在 DisplayList 中,所以只有当它是从 DisplayObject 分派时,事件才会知道其当前节点的子节点和父节点,因此可以在树上上下移动。我想象中的 City 对象不是 DisplayList 的一部分。
    • 你是对的,对此感到抱歉。用可能的解决方案更新了我的答案,看看你的想法。
    • 酷感谢 Ryan,这也是我笨拙的解决方案,我希望我的模型可以实现某种 IBubbleTree 接口并将其自身插入到冒泡系统中。虽然,既然我这么说,我可以自己为 IEventDispatchers.hmmm 的通用树编写该系统
    【解决方案3】:

    我不确定这是哪一年发布的,但我刚刚发现了这个,男孩是不是很愚蠢。为什么冒泡会依赖于显示列表?在我看来,在 AS3 中构建事件模型时,Adobe 应该为任何类实现冒泡。我需要更频繁地在不同类之间传递数据,而不是让多个显示对象相互监听。更不用说使用显示列表和根引用显示对象比引用由动态实例使用的动态实例使用的动态实例要容易得多(你明白了)。 AS2 的事件模型毕竟和 AS3 的事件模型相差不远

    【讨论】:

    • 嗯,是的,我发现冒泡在显示列表中非常方便,我也想在应用程序模型中使用它。但要满足这一点,您的模型类需要实现某种 ITree 或 IHasParent 接口系统,以便自动冒泡。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2011-08-23
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多