It seems, that the issue of deferred instantiation in Flex and the way puremvc registers the mediators, is something that almost every beginner has to deal with.
The Slacker Demo is indeed the answer to this dilemma.
But there is a slight difference between the Slacker Demo and how many developers build their navigation.
In the Slacker Demo you have to have a SplashView in order to get it work.
The SplashView doesn't have a Mediator.
But not always is it possible to have such a View without a Mediator.
For my project I needed a TabBar + ViewStack to navigate through the views.
In fact I have nested ViewStacks.
I have a MainView that contains the ViewStack and a MainViewMediator.
I register the mediator for the first view of the stack in the onRegister()method of the MainViewMediator. It works.
I thought, maybe it could help someone to see how I did it.
It is something I did when I started with puremvc, so there are imperfections there!
Especially there is an unorthodox way of getting the views' names when I register their mediators, but I had a good reason for doing so. Cliff will chide me for this!! And you should do it like in the SlackerDemo not like I did it.
I wanted to attach the example, but attachments are no longer allowed. So I'll post parts of it in here.
I hope it will help someone.
MainView<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="
http://www.adobe.com/2006/mxml"
xmlns:views="com.view.component.*" >
<mx:Script>
<![CDATA[
public static const TWO_CREATED:String = 'twoViewCreated';
public static const THREE_CREATED:String = 'threeViewCreated';
public var activeView:Object;
private function sendEvent(event:Event, action:String ):void{
activeView = event.currentTarget;
dispatchEvent(new Event( action, true ));
}
private function setActiveView(event:Event):void{
activeView = event.currentTarget.getChildAt(0);
}
]]>
</mx:Script>
<mx:TabBar id="mainTabBar" dataProvider="{mainViewStack}" />
<mx:ViewStack id="mainViewStack" childAdd="setActiveView(event)">
<views:OneView label="One" id="OneView"/>
<views:TwoView label="Two" id="TwoView" creationComplete="sendEvent(event, TWO_CREATED)"/>
<views:ThreeView label="Three" id="ThreeView" creationComplete="sendEvent(event, THREE_CREATED);"/>
</mx:ViewStack>
</mx:Canvas>
MainViewMediatorpackage com.view.mediator
{
import com.view.component.MainView;
import flash.events.Event;
import org.puremvc.as3.multicore.interfaces.IMediator;
import org.puremvc.as3.multicore.patterns.mediator.Mediator;
public class MainViewMediator extends Mediator implements IMediator
{
public static const NAME:String = 'MainViewMediator';
public function MainViewMediator(viewComponent: MainView)
{
super(NAME, viewComponent);
}
protected function get mainView(): MainView
{
return viewComponent as MainView;
}
override public function onRegister( ):void
{
mainView.addEventListener( MainView.TWO_CREATED, onViewsCreated );
mainView.addEventListener( MainView.THREE_CREATED, onViewsCreated );
//HERE IS THE TRICK: register the mediator for the first view in the stack
checkForMediator( mainView.activeView );
}
protected function onViewsCreated( event:Event ):void
{
checkForMediator( mainView.activeView );
//checkForMediator( event.currentTarget.activeView );
}
protected function checkForMediator( child:Object ):void
{
switch ( child.id )
{
case "OneView":
if ( ! facade.hasMediator( OneViewMediator.NAME ) )
facade.registerMediator(new OneViewMediator( child ));
break;
case "TwoView":
if ( ! facade.hasMediator( TwoViewMediator.NAME ) )
facade.registerMediator(new TwoViewMediator( child ));
break;
case "ThreeView":
if ( ! facade.hasMediator( ThreeViewMediator.NAME ) )
facade.registerMediator(new ThreeViewMediator( child ));
break;
}
}
}
}
The second View has also a TabBar and a ViewStack, but the post would be too long if I posted the entire code.
Ondina