as3 - 从父swf到子swf的dispatchEvent

时间:2009-09-07 04:34:45

标签: actionscript-3 events flash dispatcher

我有一个主要的“父”swf加载其他几个swfs。如果在主SWF中发生了某些事情,我需要告诉其中一个孩子swfs。

这似乎相反有效。任何一个孩子都可以简单地调用Event(),我可以设置主swf来监听事件。但是,我无法让子swf捕获父级调度的任何事件。怎么做?

5 个答案:

答案 0 :(得分:5)

好的,所以如果你已经知道了大部分内容,我很抱歉......但这似乎是一个非常普遍的问题,并不是很明显。

在AS3中,可以监听由显示列表上的对象调度的事件,因为它们将向上显示列表层次结构,而无需指定原始对象。 (当然假设事件的冒泡属性设置为true)。因此,文档类(_root的旧概念)可以响应来自任何显示对象的鼠标点击,无论嵌套有多深,

addEventListener(MouseEvent.CLICK, _onMouseClick)

在任何其他情况下 - 例如bubbling设置为false,广播器不是显示列表上的InteractiveObject,或者(在您的情况下)侦听器低于显示列表层次结构中的广播器 - 广播事件的对象必须专门监听:

fooInstance.addEventListener(Event.BAR, _bazFunc)
而非
addEventListener(Event.BAR, _bazFunc)

基本上,您需要将对父对象的引用传递给子swf,以便它可以将事件处理程序附加到它。

一种方法是通过显示列表将子事件从子类调度到父类(一旦子项加载并完全初始化)。父级使用此事件的event.target属性来引用子级并在其上设置parentClass变量。然后可以使用它来附加监听器:

package {


    class ChildClass 
    {
        private var __parentClass:ParentClass;

        // EventID to listen for in ParentClass
        public static const INITIALISED:String = "childInitialised";

        // Constructor
        function ChildClass() 
        {
            // Do initialising stuff, then call:
            _onInitialised();
        }

        private function _onInitialised():void
        {
            // Dispatch event via display hierarchy
            // ParentClass instance listens for generic events of this type
            // e.g. in ParentClass:
            //     addEventListener(ChildClass.INITIALISED, _onChildInitialised);
            //     function _onChildInitialised(event:Event):void {
            //         event.target.parentClass = this;
            //     }
            // @see mutator method "set parentClass" below
            dispatchEvent(new Event(ChildClass.INITIALISED, true);
        }

        public function set parentClass(value:ParentClass):void
        {
            __parentClass = value;

            // Listen for the events you need to respond to
            __parentClass.addEventListener(ParentClass.FOO, _onParentFoo, false, 0, true);
            __parentClass.addEventListener(ParentClass.BAR, _onParentBar, false, 0, true);
        }

        private function _onParentFoo(event:Event):void
        {
            ...
        }
    }
}

调度自定义ChildSWFEvent - 即不使用上面定义的类定义 - 将使这更灵活,因为ParentClass实例可以侦听任何子swf广播的常见ChildSWFEvent.INITIALISED事件,并传递上下文有用的信息作为附加参数。

答案 1 :(得分:1)

在父swf(Index.swf)中加载子swf(Main.swf)时,在字段变量或类变量中保留引用

fldMain = BulkLoader.getLoader("Index").getContent("Main.swf") as DisplayObject;
this.addChild(fldMain);

(我正在使用BulkLoader加载任何内容)

在添加子项之前等待调度事件是一种很好的做法(ADDED_TO_STAGE事件)

当我想向我的孩子发送一个事件时,我只想说:

fldMain.dispatchEvent(new CustomEvent(CustomEvent.INIT_CHILD,data));

答案 2 :(得分:0)

我会听每个孩子的

Event.ADDED_TO_STAGE

一旦将其添加到舞台上,您就可以引用/收听舞台上的活动。

实施例

//Child
if(stage) _init(); //Already added
else addEventListener(Event.ADDED_TO_STAGE, _init); //waiting to be added

private function _init(e:Event = null):void
{
    stage.addEventListener(CustomEvent.CHANGED, _onStageChanged);
{

我没有对此进行测试,但只要您从舞台上发送事件,它就应该有效。

//stage
dispatchEvent(new CustomEvent(CustomEvent.CHANGED));

如果您正确设置了自定义事件类,则还可以传递信息。

答案 3 :(得分:0)

我所做的是在将子项添加到舞台后在父级上添加一个侦听器以进行更改。现在,只要您想要让孩子处理自己更新,只需从父母发送Event.CHANGE即可。冒泡可能是真是假。

我认为如果你将孩子附加到舞台上(stage.addEventListener...),任何抛出Event.CHANGE的对象都可能触发孩子处理事件。

package
{
    import flash.display.*
    import flash.events.*

        public class Child extends Sprite
        {

            public function Child():void
            {
                this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true);
            }

            private function addedToStageHandler(pEvent:Event):void
            {
                trace("CHILDADDED");
                this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
                this.parent.addEventListener(Event.CHANGE, parent_changeEventHandler, false, 0, true);
            }

            private function parent_changeEventHandler(pEvent:Event):void
            {
                trace("PARENT_CHANGED");
            }
        }
}

答案 4 :(得分:0)

IMO,孩子几乎不适合了解或关心其父母。另一方面,父母几乎总是知道他们孩子的一切(因为他们直接参考他们)。因此,在这种情况下,我只需在子类上创建一个属性或方法,可以在需要时由父级设置/调用。

这具有更好性能的优势,因为创建和处理事件比简单地调用方法或设置值更昂贵。

HTH;

艾米