Search code examples
actionscript-3apache-flexadobeflex4flex4.5

In flex 4.5 parentDocument did not working as in flex 4.0. How to call parentDocument in flex 4.5?


In flex 4.0 this code works:

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" width="500" height="600">
<fx:Script>
    <![CDATA[
        import componentCanvas;

        import mx.containers.TitleWindow;
        import mx.controls.Alert;

        public function createChild():void{
            var c:componentCanvas = new componentCanvas;
            c.x = 20;
            c.y=20;
            toInclude.addChild(c);
        }
    ]]> 
</fx:Script>
<mx:Button click="createChild()"/>
<mx:Canvas id="toInclude"/>

--componentCanvas --

<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
    <![CDATA[
        import componentCanvas;
        import mx.containers.TitleWindow;
        import mx.controls.Alert;
        import mx.managers.PopUpManager;
        import popAll;

        public function oh():void{
            Alert.show("From titleWindow");
        }

        public function open():void{
            var pop:popAll = popAll(PopUpManager.createPopUp(this, popAll, true));

        }
    ]]>
</fx:Script>
<mx:Label text="Canvas" x="100" y="100"/>
<mx:Button click="open()"/>

-- popAll --

<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" x="40" y="40" close="closePopUp()">
<fx:Script>
    <![CDATA[
        import mx.managers.PopUpManager;
        public function closePopUp():void{
            super.parentDocument.oh();
            PopUpManager.removePopUp(this);
        }
    ]]>
</fx:Script>
<mx:Button click="closePopUp()"/>

When I call parentDocument in titleWindow in flex 4 all is fine. The same code in 4.5 did not work.

Is there a way to do this in Flex 4.5?


Solution

  • Calling parentDocument and using public functions across all the files is definitely not the best practice! Instead, you should really look into the Event Life Cycle in Flex and how to use it. In my opinion, public methods should really be created when you want to expose a particular functionality of your component to it's users.

    Basically, you should dispatch an event from the popAll class and listen to it within it's instance created in componentCanvas. So, to solve this issue, your code should be :

    popAll:

    <s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" x="40" y="40" close="closePopUp()">
        <fx:Script>
            <![CDATA[
                import mx.managers.PopUpManager;
    
                public function closePopUp():void{
                    this.dispatchEvent(new Event("closePopup"));
                    PopUpManager.removePopUp(this);
                }
            ]]>
        </fx:Script>
        <mx:Button click="closePopUp()"/>
    </s:TitleWindow>
    

    and componentCanvas:

    <mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
        <fx:Script>
            <![CDATA[
                import mx.controls.Alert;
                import mx.managers.PopUpManager;
    
                private var pop:popAll;
    
                public function oh():void{
                    Alert.show("From titleWindow");
                }
    
                public function open():void{
                    pop = popAll(PopUpManager.createPopUp(this, popAll, true));
                    pop.addEventListener("closePopup", onClosePopupRequested);
    
                }
    
                protected function onClosePopupRequested(event:Event):void
                {
                    pop.removeEventListener("closePopup", onClosePopupRequested); 
                    oh();
                }
    
            ]]>
        </fx:Script>
        <mx:Label text="Canvas" x="100" y="100"/>
        <mx:Button click="open()"/>
    </mx:Canvas>
    

    As per the code above, I am dispatching a new Event called as closePopup from the popAll class and listening to it where I am creating it's instance. And then once the event is caught, I am removing the event handler and then calling your oh() method from within the event handler.

    I would make a few more recommendations on your code:

    • Re-consider your naming convention of classes and methods, and please look into camel case naming convention
    • Avoid using too many public methods, instead use events to communicate between files/components. This would enable you to create loosely coupled components.
    • If you are moving to Flex 4.5, I would recommend you to use spark components instead of mx components. In my experience, they do have more versatility.
    • Look into creating constants for literals.

    Hope this helps. Cheers.