1

I have a popup that contains a TabNavigator control. The tabs are dynamically added to the TabNavigator when the popup loads. Is there a good way to tell when one of the tabs is loaded, from the tab itself?

I have a tab that requires a service call to be made, and I don't want the service call to be made unless the user actually goes and clicks the tab to view it. I could notify the tab from the popup control itself when the TabNavigator index was changed, but that doesn't seem like a good way to go about doing it. I'm wondering if there's an event or something I could hook to that would let me know the tab needed to be rendered for the first time (from within the tab control itself). Thanks in advance!

Ocelot20
  • 10,510
  • 11
  • 55
  • 96

3 Answers3

2

I think I didn't quite understand the question, so I'm trying again. I think this code will address your problem.

The trick is setting the creation policy to "none" for the component. Flex will create the tab, but not the component itself.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onCreationComplete()" layout="vertical" minWidth="955" minHeight="600">
<mx:TextArea id="log" width="100%" height="500"/>

<mx:Script>
    <![CDATA[
        import mx.containers.Canvas;
        import mx.events.FlexEvent;
        private function onCreationComplete():void{
            var canv:Canvas = new Canvas();
            canv.label = "One";
            canv.addEventListener(FlexEvent.CREATION_COMPLETE,onCreateTab);
            canv.creationPolicy="none";
            tn.addChild(canv);
            canv = new Canvas();
            canv.label = "Two";
            canv.addEventListener(FlexEvent.CREATION_COMPLETE,onCreateTab);
            canv.creationPolicy="none";
            tn.addChild(canv);
            canv = new Canvas();
            canv.label = "Three";
            canv.addEventListener(FlexEvent.CREATION_COMPLETE,onCreateTab);
            canv.creationPolicy="none";
            tn.addChild(canv);
        }

        private function onCreateTab(event:Event):void{
            log.text+=event.currentTarget.label+ " created for the very first time\n";
        }
    ]]>
</mx:Script>    
<mx:TabNavigator id="tn" width="500"/>
</mx:Application>
Jonathan Rowny
  • 7,588
  • 1
  • 18
  • 26
  • 1
    Replace `Canvas` with a spark `NavigatorContent` control and this doesn't work for some reason. Definitely threw me off for a bit. I guess I'll just have to use a `Canvas` unless you know any reason why that might be. Thanks for the solution. – Ocelot20 Jun 07 '11 at 17:24
  • For some reason I thought you were still using Flex 3, my bad. Are you one 4 or 4.5? – Jonathan Rowny Jun 07 '11 at 17:42
  • 1
    Interesting, within SkinnableContainer.as (navigatorContent's parent) I found that setting creation policy actually doesn't take affect properly... in the "creationPolicy" setter it sets the value to Auto if it's none and sets a flag! It then stores the actual creation policy in a CSS var via setStyle. It does this to avoid inheritance of that property because Spark and MX handle it differently. I don't have a quick solution for you unfortunately. – Jonathan Rowny Jun 07 '11 at 19:08
  • No problem, you've shed enough light on the situation already! Thanks for looking into it a bit more. – Ocelot20 Jun 07 '11 at 19:18
1

There's an event called the "FlexEvent.SHOW" event which should work for you. See: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/events/FlexEvent.html#SHOW

You can put this on the TabNavigator. i.e.

<mx:TabNavigator>
   <comp:SomeComp show="doSomething()" label="My Tab"/>
</mx:TabNavigator>

Or you can put it inside your component. i.e.

<mx:Canvas show="doSomething">
<!-- My Component-->
</mx:Canvas>

If you're creation policy is set, you can also do this on creationComplete, but it will only happen the FIRST time the tab is created.

Running example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" minWidth="955" minHeight="600">
    <mx:TextArea id="log" width="100%" height="500">

    </mx:TextArea>
    <mx:TabNavigator width="500">
        <mx:Canvas label="One" show="{log.text+='One Clicked\n';}"/>
        <mx:Canvas label="Two" show="{log.text+='Two Clicked\n';}"/>
        <mx:Canvas label="Three" show="{log.text+='Three Clicked\n';}"/>
        <mx:Canvas label="Four" show="{log.text+='Four Clicked\n';}"/>
    </mx:TabNavigator>
</mx:Application>

With dynamic tabs.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="cc()" layout="vertical" minWidth="955" minHeight="600">
<mx:TextArea id="log" width="100%" height="500">

</mx:TextArea>

<mx:Script>
    <![CDATA[
        import mx.containers.Canvas;
        import mx.events.FlexEvent;
        private function cc():void{
            var canv:Canvas = new Canvas();
            canv.label = "One";
            canv.addEventListener(FlexEvent.SHOW,onShow);
            tn.addChild(canv);
            canv = new Canvas();
            canv.label = "Two";
            canv.addEventListener(FlexEvent.SHOW,onShow);
            tn.addChild(canv);
        }

        private function onShow(event:Event):void{
            log.text+=event.currentTarget.label+ " clicked\n";
        }
    ]]>
</mx:Script>

<mx:TabNavigator id="tn" width="500">
</mx:TabNavigator>
</mx:Application>
Jonathan Rowny
  • 7,588
  • 1
  • 18
  • 26
  • Won't the show event fire every time the tab is clicked? He only wanted to run this code the first time the tab was clicked; not every time. – JeffryHouser Jun 07 '11 at 13:49
  • Actually, this one doesn't appear to fire when the tab is clicked. It works off the "Visible" property, which doesn't get set to false just because the tab isn't currently selected. – Ocelot20 Jun 07 '11 at 13:54
  • The show event has always worked for me on tabNavigators, but not its component children. The only other event I could think of would maybe be something with focus? – Jonathan Rowny Jun 07 '11 at 14:18
  • I just did a test with this code, code posted in first comment. Worked fine. – Jonathan Rowny Jun 07 '11 at 14:21
  • I believe your example produces different results because you are not dynamically loading the tabs. – Ocelot20 Jun 07 '11 at 14:30
  • I just tried it with dynamic tabs and it still worked... posted code above again. – Jonathan Rowny Jun 07 '11 at 14:47
0

Read up on the Flex Component LifeCycle. Based on what you describe, I would probably listen for the creationComplete event on the tab's content.

JeffryHouser
  • 39,401
  • 4
  • 38
  • 59
  • Unfortunately, creationComplete is called when the tab is added to the navigator, not when it is being displayed in the navigator for the first time. – Ocelot20 Jun 07 '11 at 13:55
  • @Ocelot20 I wasn't sure, sorry. The TabNavigator does weird thing w/ deferred instantiation, where the 'child/tab source' will be created, but not the children's children or something like that. I don't use the component enough to have that stuff down pat. You could use updateComplete and use a flag to tell whether or not you already have the data. Except I bet updateComplete will fire right after creationComplete. – JeffryHouser Jun 07 '11 at 14:07
  • You are correct, updateComplete also gets called when the content is added. Perhaps this is not easily accomplished and I should just notify the tab from outside. – Ocelot20 Jun 07 '11 at 14:10