将dispatchEvent发送给child:example不起作用? (flash,as3)

时间:2011-10-15 19:31:23

标签: flash actionscript-3 event-handling dispatchevent

我想将dispatchEvent发送到已加载的swf,放入movieclip。我发现a good topic about it但我的例子不起作用,“跟踪”没有出现。

修改

  • 我有main.as
  • 另一个类submenu.as,我在main.as
  • 中导入
  • 当我点击main.as中的“主要”菜单时,我想向dispatchEvent发送submenu.as(因为我希望子菜单更改其中一个项目,当我点击main.as中的“主菜单”时,我需要发送dispatchEventsubmenu.as
  • 所以我在dispatchEvent clickButton
  • 中的main.as方法中添加了Event.CHANGE
  • submenu.as中,我想听听event.CHANGE,这就是我在下面写的内容

编辑结束。

在我的父类中:每次我点击菜单:

dispatchEvent(new Event(Event.CHANGE));

stage.dispatchEvent(new Event(Event.CHANGE));

在我的孩子班上:

public function initStage (e:Event){
[…]
this.parent.addEventListener(Event.CHANGE, switchItem, false, 0, true);

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

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

从子SWF,从loaderInfo访问。

loaderInfo.sharedEvents.addEventListener(Event.CHANGE, switchItem, false, 0, true);

根据你的编辑,听起来像main.as和submenu.as都在同一个SWF中,也许问题是你试图将事件搞砸了?

您可以针对子对象调度事件,或使用一些静态/单例模式,例如:

public static var dispatcher:IEventDispatcher = new EventDispatcher();

针对调度程序发送事件,并侦听调度程序中的事件。

这类似于您尝试在舞台上发送事件的方式;但是,孩子必须听取舞台而不是“this.parent”。我不建议这样做。

否则,让父进程将事件传递给子进程,就像在main.as dispatch事件中一样,将子进程从submenu.as定义。

答案 1 :(得分:1)

据我所知,该主题并不适用于您,除非您实际上是在运行时加载swf并尝试侦听它们之间的事件。 我还建议不要在显示列表上使用层次结构来收集引用,除非层次结构本身确实很重要。例如,也许这个菜单在关闭时将其自身从其父容器中删除,或者需要将displayObject添加到其所在的同一容器中,并且不关心容器是什么。使用层次结构强制您维护引用的层次结构,这有时会使得在不断增长的应用程序上进行更改变得困难。 下面是您可能正在寻找的一个示例,它不使用显示列表来收集引用:

public class Main extends Sprite 
{
    private var menu:SubMenu;

    public function Main():void 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        menu = new SubMenu(this);
        addChild(menu)  //This is not neccessary for them to communicate
        dispatchEvent(new Event(Event.CHANGE));
    }

}

public class SubMenu extends Sprite
{
    private var mainMenu:IEventDispatcher;  //This could be typed as Main instead of IEventDispatcher if needed. 
                                            //Sprites are however IEventDispatchers

    public function SubMenu(mainMenu:IEventDispatcher) 
    {
        this.mainMenu = mainMenu;
        mainMenu.addEventListener(Event.CHANGE, switchItem, false, 0, true);
    }

    private function switchItem(event:Event):void
    {
        trace("Parent_Changed")
    }
}

以下是使用显示列表层次结构的示例(我不推荐):

public class Main extends Sprite 
{
    private var menu:SubMenu;

    public function Main():void 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        menu = new SubMenu();
        addChild(menu)  //This is neccessary, and the menu cannot be added to a different parent

        dispatchEvent(new Event(Event.CHANGE));

    }
}
public class SubMenu extends Sprite
{

    public function SubMenu() 
    {
        //Neccessary because submenu will not have a parent when its first instantiated.
        //When its on the stage then you can have it grab its parent and add a listener.
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);

    }

    private function init(event:Event = null):void
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);

        //Parents available
        parent.addEventListener(Event.CHANGE, switchItem, false, 0, true);
    }

    private function switchItem(event:Event):void
    {
        trace("Parent_Changed")
    }

}

答案 2 :(得分:1)

我看到两种可能的可能性。

首先,尝试添加断点或跟踪this.parent函数中设置的initStage()。如果您说的是dispatchEvent()stage.dispatchEvent(),但实际上将子项添加到Main中的对象而不是Main本身的实例中,那么它可能正在侦听事件的错误对象。

其次,确保在事件被触发之前initStage()实际执行。调度事件时可能没有设置侦听器。