Domanda

I've been having some trauma with an event being dispatched, but I can't detect it in the main app. I've knocked up an example of the code, removing redundant stuff, so it looks a little unusual!

I have a main app, (Air) which has a canvas with a single button. This single button opens a PopUp titlewindow which has a datagrid in it. On clicking the datagrid a really simple custom event is dispatched which is heard at the lowest level, but not calling canvas or main app. I assume its how i define the listener at the upper levels, but it's really driving me mad! Code Below:

mainApp.mxml..........

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
                                        layout="absolute"
                                        creationComplete="{onCreationComplete()}" 
                                        xmlns:components="components.*"
                                         >

<mx:Script>
    <![CDATA[

        import components.lowestLevel;

        private var lowest:lowestLevel;

        private  function onCreationComplete():void
        {
                 lowest = new lowestLevel;

                 lowest.addEventListener('myEventType',mainAppListenerHandler);

        }


        private function mainAppListenerHandler(event:Event):void
        {
            trace("ive been heard  in main app")
        }   

    ]]>

</mx:Script>

        <components:middleLevel/>

</mx:WindowedApplication>

middleLevel.mxml

<?xml version="1.0" encoding="utf-8"?>
    <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" 
                    width="900" 
                    height="50"
                    creationComplete="{ addEventListener('myEventType',listenerHandler);}"
                    >

    <mx:Script>
        <![CDATA[
            import mx.core.Application;
            import mx.managers.PopUpManager;
            import actionScript.sql;

            private function launchViewAllLoads(event:MouseEvent):void
            {            

                sql.getSourceFilesToView()

                var win:lowestLevel = new lowestLevel();

                PopUpManager.addPopUp(win,parent,true);
                PopUpManager.centerPopUp(win); 

            }

            private function listenerHandler(event:Event):void
            {
                trace("im heard at the Middle level" )      
            }           

]]>


    </mx:Script>

    <mx:Button  id="btnViewAllLoads"
                        label="View Current"
                        click="{launchViewAllLoads(event)};"
                         />

    </mx:Canvas>

lowestLevel.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical" width="800" height="550"
    title="View All Loads" horizontalAlign="center"
    creationComplete="{ addEventListener('myEventType',listenerHandler);}"
      >

    <mx:Script>
        <![CDATA[

            import mx.core.IFlexDisplayObject;
            import mx.events.CloseEvent;
            import mx.managers.PopUpManager;


            private function listenerHandler(event:Event):void
            {
                trace("im heard at the lowest level" )      
            }


            private function sourceFilesToViewClickedHandler():void
            {   
                PopUpManager.removePopUp(this as IFlexDisplayObject);

                var myEvent:Event = new Event('myEventType' ,true,true);
                dispatchEvent(myEvent); 

            }

        ]]>
    </mx:Script>

        <mx:Canvas  id="cSourceFiles" width = "100%" height="100%">

                <mx:DataGrid    id="dgSourceFiles"  
                                        click="{sourceFilesToViewClickedHandler()}">

                <mx:columns>
                    <mx:DataGridColumn dataField="Batch"  headerText="Batch" width="80"/>
                    <mx:DataGridColumn dataField="LastUpdated"  headerText="Last Updated" width="85"/>                                  
                </mx:columns>

            </mx:DataGrid>


        </mx:Canvas>
</mx:TitleWindow>
È stato utile?

Soluzione

I see some issues here. First is this in your mainApp.mxml:

private  function onCreationComplete():void
{
         lowest = new lowestLevel;

         lowest.addEventListener('myEventType',mainAppListenerHandler);

}

You are creating an instance of lowestLevel and adding an event listener to this. But, this is not the same instance created in middleLevel. If you have two independent instances of a component; dispatching an event in one instance will not cause event listeners on the other instance to fire.

Since your mainApp's lowestLevel instance is never added to the stage in any manner; the user can never interact with it firing off the event.

You can try this:

private  function onCreationComplete():void
{
         this.addEventListener('myEventType',mainAppListenerHandler);
}

This will add the event listener on the mainApp file. As the event bubbles; the event is dispatched on every class in the display hierarchy. So, this should work.

The second issue I see is that the PopUpManager creates its windows as a child of the SystemManager component; which is independent of the current display hierarchy. To quote the docs:

all popups are parented by the SystemManager.

So, dispatching an event from the lowestLevel will not bubble to middleLevel or mainApp because it is not actually the "lowest level". It is almost as it exists in a parallel hierarchy.

The solution would be to listen for the event directly on the lowestLevel instance in middleLevel and redispatch it.

Altri suggerimenti

What if you redispatch the same event:

private function listenerHandler(event:Event):void {
    trace("im heard at the Middle level" )      
    dispatchEvent(event);
}

By using a callback:

var callback = function():void {
   // do some stuff here
}
lowest = new lowestLevel(callback);

And later, instead of dispatching the event:

private var _callback:Function;
public function lowestLevel(callback:Function):void {
  _callback = callback;
}
private function sourceFilesToViewClickedHandler():void {   
  PopUpManager.removePopUp(this as IFlexDisplayObject);
  _callback();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top