I can already see there aren't that many takers on this so here's what I have going to solve this problem. While not the most elegant it does work well but, as always, there are probably better ways about this.
Goes like this...
1. App. fires up and creates all the components in Application.mxml including the register component.
2. Register component inits by registering a callback to be used later by ApplicationStartupCommand
3. StartupCommand fires up and sends out the selfRegister event
4. All components register their mediator and then proceed to load the component defined in the loadit function.
5. loadIt loads up the component and then calls the supplied function to add it to the parent
You should notice that ComponentMediator constructor uses a unique ID for each mediator so you can have more than one of the same components available at the same time.
Feedback/Critique/etc. always welcome.
flexman...
Root MXML of a sample component that does user registration
Application.mxml
------------------------------------------------
<mx:HBox width="50%" height="100%">
<components:Register id="register" width="100%"/>
</mx:HBox>
Register.mxml (referenced above)
------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="
http://www.adobe.com/2006/mxml" width="100%" height="100%" preinitialize="init()">
<mx:Script>
<![CDATA[
import org.puremvc.as3.multicore.interfaces.IFacade;
import com.meshell.view.RegisterCanvasMediator;
import com.me.common.StartupEvent;
import mx.core.Application;
import com.pa.common.Constants;
private function init():void{
Application.application.systemManager.addEventListener("SelfRegister", selfRegister);
}
private function selfRegister(evt:StartupEvent):void{
var af:IFacade = evt.startupData.appfac;
var rcm:RegisterCanvasMediator = new RegisterCanvasMediator(this);
af.registerMediator(rcm);
rcm.loadIt(Constants.WIDGET_REGISTER, Constants.WIDGET_REGISTER_URL, rcm.addToParent);
}
]]>
</mx:Script>
</mx:VBox>
RegisterCanvasMediator.as
package com.me.shell.view{
import com.me.shell.view.components.RegisterCanvas;
import flash.display.DisplayObject;
public class RegisterCanvasMediator extends ComponentMediator{
public function RegisterCanvasMediator( viewComponent:RegisterCanvas ){
super(viewComponent);
}
public function addToParent(myID:String, moduleInstance:Object):void{
var registerMediator:RegisterCanvasMediator = facade.retrieveMediator(myID) as RegisterCanvasMediator;
registerMediator.registerCanvas.addChild(moduleInstance as DisplayObject);
}
}
}
ComponentMediator.as (base class for RegisterCanvasMediator.as)
package com.me.shell.view
{
import com.me.shell.ApplicationShellConstants;
import com.me.shell.model.ModuleDescriptor;
import com.me.shell.view.components.RegisterCanvas;
import flash.system.ApplicationDomain;
import mx.core.UIComponent;
import mx.events.ModuleEvent;
import mx.modules.IModuleInfo;
import mx.modules.ModuleManager;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.utilities.fabrication.components.FlexModuleLoader;
import org.puremvc.as3.multicore.utilities.fabrication.patterns.mediator.FlexMediator;
public class ComponentMediator extends FlexMediator{
private var _module:IModuleInfo;
private var _uniqueID:String;
private var _addToParent:Function;
private function get module():IModuleInfo{
return _module;
}
private function set module(mod:IModuleInfo):void{
_module = mod;
}
private function get uniqueID():String{
return _uniqueID;
}
private function set uniqueID(id:String):void{
_uniqueID = id;
}
private function get addToParent():Function{
return _addToParent;
}
private function set addToParent(atp:Function):void{
_addToParent = atp;
}
public function ComponentMediator( viewComponent:UIComponent ){
uniqueID = viewComponent.id;
super(uniqueID, viewComponent );
}
public function loadIt(md:String, murl:String, atp:Function):void{
var moduleDescriptor:ModuleDescriptor = new ModuleDescriptor(md);
moduleDescriptor.url = murl;
sendNotification(ApplicationShellConstants.ADD_MODULE, moduleDescriptor);
addToParent = atp;
var moduleLoader:FlexModuleLoader = new FlexModuleLoader();
module = ModuleManager.getModule(moduleDescriptor.url);
module.data = moduleDescriptor;
module.addEventListener(ModuleEvent.READY, moduleReadyListener);
module.load(ApplicationDomain.currentDomain);
}
private function moduleReadyListener(event:ModuleEvent):void {
var module:IModuleInfo = event.module;
var moduleDescriptor:ModuleDescriptor = event.module.data as ModuleDescriptor;
var moduleInstance:Object = event.module.factory.create();
moduleInstance.router = applicationRouter;
moduleInstance.defaultRouteAddress = applicationAddress;
moduleInstance.id = moduleDescriptor.getElementID();
// call the function to do mediator specific work...
addToParent(uniqueID, moduleInstance);
}
public function get registerCanvas():RegisterCanvas{
return viewComponent as RegisterCanvas;
}
public override function listNotificationInterests():Array{
return [];
}
public override function handleNotification(notification:INotification):void{
switch(notification.getName()){
}
}
}
}
ApplicationStartupCommand.as
// this is sent out to have all the components load themselves...
var selfRegister:StartupEvent = new StartupEvent("SelfRegister", true);
var self:Object = new Object();
self.appfac = this.facade;
selfRegister.startupData = self;
Application.application.systemManager.dispatchEvent(selfRegister);