I'd like to add that your working condition has alot to do with how you would setup your mediators and the entire facade for that matter. I have the unfortunate displeasure of working at a company where my projects are 'design by committee' with no documentation presented to me, unqualified people making requests for changes and new features whenever they want, etc... PureMVC has been my code equivalent to LEGOs.
I have adopted my own custom practice for communication between components and mediators that has been very handy for my situation. Quite often I start off with a component and mediator pair, but after a Monday meeting, I may come away with over a dozen changes / added features. It's quite ridiculous. So, as I get to implementing the block outs for the view, I look through the component and see what needs to be it's own component based on what things are similar, and cut that xml and paste it into a new component and setup a new mediator.
So, here is what I do that is specific to my setup that has helped me in this crazy world of flux that I spend 40 hours a week in:
- Components are responsible for creation and destruction of their mediators
This really helps when I use view states and the includeIn or excludeFrom tag for a component (seems to happen alot latey as I think these guys are seeing how far they can push me.
// some example code
private function init():void
{
_facade = MainFacade.getInstance(Main.NAME);
_facade.registerMediator(new AdminMediator(this));
}
- Make sure you have proxies for your data. You wont get very far with the above if you dont - Poof! Gone the minute the state changes...
- Custom payload-able ViewEvent that is dispatched to the mediator from the component.
This is how the component messages it's mediator. The event has no static constants defined. It passes constants defined in the component:
// defined constants
public static const INSERT_NEW_TESTIMONIAL:String = 'insert_new_testimonial';
public static const EDIT_CURRENT_TESTIMONIAL:String = 'edit_current_testimonial';
// and an example of the dispatch. This one has a payload
dispatchEvent(new ViewEvent(EDIT_CURRENT_TESTIMONIAL, editItem));
Then the mediator has registered listeners in it's constructor
public function AdminMediator(viewComponent:Object)
{
super(NAME, viewComponent);
// No references to the facade are allowed in the constructor.
view.addEventListener(AdminView.INSERT_NEW_TESTIMONIAL, viewEventHandler);
view.addEventListener(AdminView.EDIT_CURRENT_TESTIMONIAL, viewEventHandler);
}
and then my viewEventHandler is very similar to the handleNotifications in that it uses a switch statement:
private function viewEventHandler(e:ViewEvent):void
{
switch (e.type)
{
case AdminView.INSERT_NEW_TESTIMONIAL:
sendNotification(MainFacade.INSERT_NEW_TESTIMONIAL, e.data);
break;
case AdminView.EDIT_CURRENT_TESTIMONIAL:
sendNotification(MainFacade.EDIT_CURRENT_TESTIMONIAL, e.data);
break;
}
}
As a result, I end up with very consistent mediators in design and refactoring to add a new mediator is quite painless with the help of copy/paste to move over some case conditions and the old find and replace for updating the view names. And yes, the necessary constants are moved to the new component as well.
Mediator in 5 seconds...
Until some serious support for templates becomes available in FB, I use FlashDevelop to create my actors. It's a little clunky having 2 IDEs open, but it saves time.
If you have FD, you are welcome to my mediator template. Here is the code below for the fdt file:
package $(Package) $(CSLB){
import org.puremvc.as3.multicore.interfaces.IMediator;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.patterns.mediator.Mediator;
import $(Package).*;
/**
* ... PureMVC - Mediator Class Multi core
*
*/
public class $(FileName) extends Mediator implements IMediator
{
// Cannonical name of the Mediator
public static const NAME:String = "$(FileName)";
public function $(FileName)(viewComponent:Object)
{
super(NAME, viewComponent);
// No references to the facade are allowed in the constructor.
}
override public function onRegister () : void
{
// Make any calls to the facade here:
}
override public function getMediatorName():String
{
return $(FileName).NAME;
}
override public function listNotificationInterests():Array
{
return [];
}
override public function handleNotification(note:INotification):void
{
switch (note.getName())
{
default:
break;
}
}
/* IMPORT view class and View event
private function viewEventHandler(e:ViewEvent):void
{
switch (e.type)
{
default:
break;
}
}
public function get view(): // add View Class
{
return viewComponent as // add View Class
}
*/
}
}
and here's my view event. I have a common.events package in my source.
package common.events
{
import flash.events.Event;
public class ViewEvent extends Event
{
public var data:Object;
public function ViewEvent(type:String, data:Object=null, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.data = data;
}
override public function clone() : Event
{
return new ViewEvent(this.type, this.data, this.bubbles, this.cancelable);
}
override public function toString():String
{
return formatToString("ViewEvent", "type", "bubbles", "cancelable", "eventPhase", "data");
}
}
}
So yeah... My code is like LEGOs... or should I say Cliff-Blocks?

I don't know that this would be considered a 'best practice' by any means, but it does allow me to make fairly drastic changes quickly and without bugs popping up provided I moved all the parts that were related to the new components and mediators.
I'd actually be interested to see how others are handling changes in design.... Provided they are plagued with 'Design by Committee' like I am.
TJ