Over 10 years of community discussion and knowledge are maintained here as a read-only archive.
<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" xmlns:loginComp="com.pt.onedesign.user_manager.view.components.Login.*" xmlns:userManagerComp="com.pt.onedesign.user_manager.view.components.UserManager.*" initialize="facade.startupApp(this)"> <mx:Script> <![CDATA[ import com.pt.onedesign.user_manager.view.ApplicationMediator; import com.pt.onedesign.user_manager.ApplicationFacade; private var facade:ApplicationFacade = ApplicationFacade.getInstance(); [Bindable] public var currentViewSelector:uint = ApplicationMediator.LOGIN_PANEL; public var activeView:Object; ]]> </mx:Script> <mx:Binding source="appView.selectedChild" destination="activeView"/> <mx:ViewStack id="appView" resizeToContent="true" selectedIndex="{currentViewSelector}"> <loginComp:LoginPanel id="loginPanel" /> <userManagerComp:UserManager id="userManagerPanel"/> </mx:ViewStack> </mx:Application>
package com.pt.onedesign.user_manager.view{ import com.pt.onedesign.user_manager.model.LoginProxy; import com.pt.onedesign.user_manager.model.UserProxy; import mx.controls.Alert; import mx.core.Container; import org.puremvc.as3.interfaces.IMediator; import org.puremvc.as3.interfaces.INotification; import org.puremvc.as3.patterns.mediator.Mediator; public class ApplicationMediator extends Mediator implements IMediator { //Define Proxy private var _loginProxy : LoginProxy; private var _userProxy : UserProxy; //Define static const for mediator public static const NAME:String = "ApplicationMediator"; // Define const names for change ViewStack views. public static const LOGIN_PANEL : Number = 0; public static const USER_MANAGER_PANEL : Number = 1; public function ApplicationMediator( viewComponent: Main ):void { super ( NAME, viewComponent ); // local reference to the LoginProxy _loginProxy = facade.retrieveProxy(LoginProxy.NAME) as LoginProxy; facade.registerMediator(new LoginPanelMediator(app.loginPanel)); //facade.registerMediator(new UserListMediator(app.userManagerPanel.userList)); } protected function get app(): Main { return viewComponent as Main; } override public function listNotificationInterests():Array { return [ LoginProxy.LOGIN_SUCCESS, LoginProxy.LOGIN_FAILED ] } override public function handleNotification( note:INotification ):void { var child:Container; switch ( note.getName() ) { case LoginProxy.LOGIN_FAILED: Alert.show("Invalid username or password, please try it again.","Login Failed"); app.currentViewSelector = LOGIN_PANEL; break; case LoginProxy.LOGIN_SUCCESS: app.currentViewSelector = USER_MANAGER_PANEL; facade.registerMediator(new UserListMediator(app.activeView.userList)); break; } } }}
<?xml version="1.0" encoding="utf-8"?><mx:Canvas width="900" xmlns:comps="com.pt.onedesign.user_manager.view.components.UserManager.components.*" xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:HBox horizontalGap="10" horizontalAlign="center" verticalAlign="top" width="100%" paddingTop="15"> <mx:VBox verticalGap="10"> <comps:UserList id="userList"/> </mx:VBox> <comps:UserForm id="userForm"/> </mx:HBox></mx:Canvas>
case LoginProxy.LOGIN_SUCCESS: app.currentViewSelector = USER_MANAGER_PANEL; app.activeView.creationPolicy=all; <------------ It make the other components avaible but without this they still null :| facade.registerMediator(new UserListMediator(app.activeView.userList));break;
package com.pt.onedesign.user_manager.view{ import com.pt.onedesign.user_manager.model.LoginProxy; import com.pt.onedesign.user_manager.model.UserProxy; import mx.controls.Alert; import mx.core.Container; import org.puremvc.as3.interfaces.IMediator; import org.puremvc.as3.interfaces.INotification; import org.puremvc.as3.patterns.mediator.Mediator; public class ApplicationMediator extends Mediator implements IMediator { //Define Proxy private var _loginProxy : LoginProxy; private var _userProxy : UserProxy; //Define static const for mediator public static const NAME:String = "ApplicationMediator"; // Define const names for change ViewStack views. public static const LOGIN_PANEL : int = 0; public static const USER_MANAGER_PANEL : int = 1; public function ApplicationMediator( viewComponent: Main ):void { super ( NAME, viewComponent ); // local reference to the LoginProxy _loginProxy = facade.retrieveProxy(LoginProxy.NAME) as LoginProxy; facade.registerMediator(new LoginPanelMediator(app.loginPanel)); //facade.registerMediator(new UserListMediator(app.userManagerPanel.userList)); } override public function listNotificationInterests():Array { return [ LoginProxy.LOGIN_SUCCESS, LoginProxy.LOGIN_FAILED ] } override public function handleNotification( note:INotification ):void { switch ( note.getName() ) { case LoginProxy.LOGIN_FAILED: Alert.show("Invalid username or password, please try it again.","Login Failed"); app.currentViewSelector = LOGIN_PANEL; break; case LoginProxy.LOGIN_SUCCESS: app.currentViewSelector = USER_MANAGER_PANEL; facade.registerMediator(new UserListMediator(app.activeView.userList)); facade.sendNotification(UserProxy.GET_USERS_LIST); break; } } protected function get app(): Main { return viewComponent as Main; } }}
[Bindable] public var currentViewSelector:int = ApplicationMediator.LOGIN_PANEL; public var activeView:Object; ]]> </mx:Script> <mx:Binding source="appView.selectedChild" destination="activeView" /> <mx:ViewStack id="appView" resizeToContent="true" selectedIndex="{currentViewSelector}" > <loginComp:LoginPanel id="loginPanel"/> <userManagerComp:UserManager id="userManagerPanel"/> </mx:ViewStack>
The best practice that has emerged (but is not yet reflected in many demos) is to hold off facade interaction until onRegister. This allows the Mediator or Proxy to be sure it's ready to participate in any conversations it may start. If it isn't registered and it performs an action that results in a Notification it should receive, it will miss that Notification. If another actor needs to retrieve it as a result of this action, that actor will not succeed unless the initiating actor is already registered.Another good reason to adopt this practice is that in MultiCore, it is required. You cannot access the concrete facade from the constructor of your Notifier sublcasses in MultiCore. There, you must wait until initializeNotifier (unique to MultiCore, and prior to registration), and onRegister, which is more desirable for the same reasons stated above for the Standard version.
case LoginProxy.LOGIN_SUCCESS: app.currentViewSelector = USER_MANAGER_PANEL; facade.registerMediator(new UserListMediator(app.activeView.userList)); facade.sendNotification(UserProxy.GET_USERS_LIST); break;
This is still not as good as following a protocol so, I'm refactoring the code in the FAQ and creating a demo today that eliminates the guesswork. More soon.