4

I'm giving it a try and it happens that I'm having a hard time figuring out how to pass data between ViewNavigator in a TabbedMobileApplication.

<s:TabbedMobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark">
    <fx:Declarations>
    </fx:Declarations>

    <s:ViewNavigator id="nav1" label="Nav1" firstView="views.Nav1Home" width="100%" height="100%"/>
    <s:ViewNavigator id="nav2" label="Nav2" firstView="views.Nav2Home" width="100%" height="100%"/>

</s:TabbedMobileApplication>

How can I pass data between nav1 and nav2? I know how to do it in between navigation views.

Thanks, B.

Bruno Santos
  • 1,530
  • 1
  • 15
  • 22

5 Answers5

2

I'd like to add that I prefer a more loosely coupled communication mechanism over what was already discussed. I prefer some type of event aggregation system where decoupled components send messages without each other knowing about the other.

This type of eventing system is built into lightweight frameworks such as Parsely and Robot Legs.

It is mostly a style thing, but in my experience, the more we tightly couple our communications like this, the more we pay for it down the road.

Food for thought, I suppose. :)

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
  • I agree that this is a little cumbersome, but so far the only way I have found for doing it. Regarding the mechanism to access data, I would think that it would be enough to have a single static data property accessible through the MobileApplication instance. Pretty much like a normal singleton. The views should then be able to access it. – Bruno Santos Feb 14 '11 at 18:40
2

A simple way is to add your data object to the view with the ViewNavigator. Then in the children views, use this to get the data:

this.parentDocument.yourDataObject
Mike007
  • 530
  • 1
  • 5
  • 10
1

Unless I'm missing something here, what you're going to want to do is and a script block in here and listen to your ViewNavigators for events. Then in th handler for the event, call a public functions on the targeted ViewNav.

<s:TabbedMobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="init()">
    <fx:Declarations>
    </fx:Declarations>

    <fx:script><![CDATA[
        private function init():void{
               nav1.addEvenListener(CustomEvent.DATA, onData);
        }

        private function onData(ev:CustomEvent):void{
               nav2.setData(ev.data);
        }
    ]]></fx:script>



    <s:ViewNavigator id="nav1" label="Nav1" firstView="views.Nav1Home" width="100%" height="100%"/>
    <s:ViewNavigator id="nav2" label="Nav2" firstView="views.Nav2Home" width="100%" height="100%"/>

</s:TabbedMobileApplication>
TJ Gillis
  • 675
  • 2
  • 6
  • 20
1

TJ already got it right. Just posting final example in case someone get the same issue:

TestApplication.mxml

<s:TabbedMobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       creationComplete="init()">
<fx:Declarations>
</fx:Declarations>

<fx:Script>
    <![CDATA[

        private function init():void{
            nav1.activeView.addEventListener(CustomEvent.DATA, onData);
            nav2.activeView.addEventListener(CustomEvent.DATA, onData);
        }

        private function onData(ev:CustomEvent):void{
            nav1.activeView.data = ev.data;
            nav2.activeView.data = ev.data;
        }           
    ]]>
</fx:Script>

<s:ViewNavigator id="nav1" label="Nav1" firstView="views.Nav1Home" width="100%" height="100%"/>
<s:ViewNavigator id="nav2" label="Nav2" firstView="views.Nav2Home" width="100%" height="100%"/>

CustomEvent.as

package
{
import flash.events.Event;

public class CustomEvent extends Event
{   
    public static var DATA:String = "DATA_EVENT";
    public var data:Object = null;

    public function CustomEvent(data:Object, type:String, bubbles:Boolean=false, cancelable:Boolean=false)
    {
        super(type, bubbles, cancelable);
        this.data = data;
    }
}

}

views.Nav1Home.mxml

<?xml version="1.0" encoding="utf-8"?>

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<fx:Script>
    <![CDATA[
        private function init(): void {
            this.addEventListener(FlexEvent.REMOVING, removedHandler);
        }

        private function removedHandler(event:Event):void {
            trace("Removed from stage: " + data);
            this.dispatchEvent(new CustomEvent("Data from Nav1 Event", CustomEvent.DATA));
        }
    ]]>
</fx:Script>

views.Nav2Home.mxml

<?xml version="1.0" encoding="utf-8"?>

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<fx:Script>
    <![CDATA[           
        private function init(): void {
            this.addEventListener(FlexEvent.REMOVING, removedHandler);
        }

        private function removedHandler(event:Event):void {
            trace("Removed from stage: " + data);
            this.dispatchEvent(new CustomEvent("Data from Nav2 Event", CustomEvent.DATA));
        }
    ]]>
</fx:Script>

Bruno Santos
  • 1,530
  • 1
  • 15
  • 22
0

easiest way if using viewNavigator to transition between views is just pass a data object to the view:

in View1:

private function view1_clickHandler(event:Event):void {
  var trans:FlipViewTransition = new FlipViewTransition();
  var obj:Object = new Object();
  obj.showPrevBtn = false;                      
  FlexGlobals.topLevelApplication.tabNavigator.pushView(View2, obj, null, trans);
}

in View2 :

protected function view2_addedToStageHandler(event:Event):void
{
  if(prevBtn != null && this.data != null && this.data.showPrevBtn === true) {
    prevBtn.visible = true;
  } else if(prevBtn != null && this.data != null && this.data.showPrevBtn === false)  {
    prevBtn.visible = false;
  }
}
annono
  • 1