Search code examples
flashactionscript-3event-handlingdispatchevent

send dispatchEvent to child : example doesn't work? (flash, as3)


I'd like to send a dispatchEvent to a loaded swf, put into a movieclip. I found a good topic about it but my example doesn't work, the "trace" doesn't appear.

Edit.

  • I have a main.as
  • another class: submenu.as, that I import in main.as
  • when I click on the "main" menu in main.as, I would like to send a dispatchEvent to submenu.as (because I'd like the submenu to change one of its items, when I click on the "main menu" in main.as, so I need to send a dispatchEvent to submenu.as)
  • so I put a dispatchEvent in the method clickButton in my main.as: Event.CHANGE
  • and in the submenu.as, I'd like to listen to this event.CHANGE, and that's what I wrote below

End of edit.

In my parent class: each time I click on the menu:

dispatchEvent(new Event(Event.CHANGE));

or

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

and in my child class :

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

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

Any idea?


Solution

  • As far as I can tell that topic doesn't apply too much to you, unless you actually are loading a swf at runtime and are trying to listen to events between them. I would also advise not using hierarchy on the display list for gathering references unless the hierarchy itself is indeed important. For example, maybe this menu removes itself from its parent container on close, or needs to add a displayObject to the same container its on, and doesn't care what the container is. Using hierarchy forces you to maintain that hierarchy for the references, which can sometimes make it hard to make changes on a growing application. Heres an example of what you may be looking for that doesn't use the display list to gather references:

    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")
        }
    }
    

    Heres an example using the display list hierarchy (I wouldn't recommend it) :

    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")
        }
    
    }