tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/513-mediator-dispatches-on-maplistner-to-view-but-not-on-elements-within-the-viewRobotlegs: Discussion 2012-06-22T07:36:26Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/145128562012-03-15T16:05:03Z2012-03-15T16:05:03ZMediator dispatches on mapListner to view but not on elements within the view<div><p>I recommend <em>never</em> listening to sub-objects. Have the
view manage its subobject events and relay them to the mediator
accordingly. I also recommend not using generic events like a
MouseEvent, opting for custom events that are specific to your
problem domain.</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/145128562012-03-15T16:19:56Z2012-03-15T16:19:56ZMediator dispatches on mapListner to view but not on elements within the view<div><p>+1 for almost-never listening to sub objects (too many race
condition / replacement of child issues).</p>
<p>I like signals for view-> mediator coms too.</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/145128562012-03-15T16:21:14Z2012-03-15T16:21:15ZMediator dispatches on mapListner to view but not on elements within the view<div><p>hmm ok...</p>
<p>So in my view I would apply standard
<code>addEventListeners</code> to each of my menu buttons and each
of the mouseEventHandling functions I would then?</p>
<p>How would I link to the mediator?</p>
<p>At a guess, would I place <code>dispatchEvent( new
MouseEvent(MouseEvent.CLICK) );</code> in to each of the views
mouseEventHandling functions and then in the mediator make
listeners which listen to the view for these events and then fire
the signals via
<code>signalClassName.dispatch(e.target.name);</code></p>
<p>I'm trying to work out how to use signals. trying lol</p>
<p>Also how does one listen to a signal, eg I would like to only
start my application once my model has loaded some xml. I've not
quite got to this part yet but any info you could supply would be
much appreciated. :)</p></div>actimel76tag:robotlegs.tenderapp.com,2009-10-18:Comment/145128562012-03-15T16:33:59Z2012-03-15T16:33:59ZMediator dispatches on mapListner to view but not on elements within the view<div><p>Hi there,</p>
<p>you can make the signals unique and meaningful, and they would
be properties of the view.</p>
<p>So - taking the example of a log in panel that has 2 fields and
2 buttons (submit and cancel)</p>
<p>In the view you have:</p>
<pre>
<code>public function get submitted():Signal
{
// the ||= operator is just for lazy instantiation
return _submitted ||= new Signal(String, String);
}
public function get cancelled():Signal
{
return _cancelled ||= new Signal();
}</code>
</pre>
<p>The actual handlers on the individual buttons would simply
need:</p>
<pre>
<code>cancelButton.addEventListener(MouseEvent.CLICK, cancelClickedHandler);
submitButton.addEventListener(MouseEvent.CLICK, submitClickedHandler);
private function cancelClickedHandler(e:MouseEvent):void
{
cancelled.dispatch();
}
private function submitClickedHandler(e:MouseEvent):void
{
submitted.dispatch(username.text, password.text);
}</code>
</pre>
<p>In the (SignalMediator) mediator you'd have:</p>
<pre>
<code>override public function onRegister():void
{
addToSignal(view.submitted, handleSubmit);
addToSignal(view.cancelled, handleCancel);
}
protected function handleSubmit(username:String, password:String):void
{
dispatch( new AccountLoginEvent(AccountLoginEvent.LOGIN_REQUESTED, username, password) );
}</code>
</pre>
<p>etc</p>
<p>hth,</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/145128562012-03-15T19:26:40Z2012-04-24T12:57:26ZMediator dispatches on mapListner to view but not on elements within the view<div><p>But in my case of having 6 buttons which change page content if
I handle wth a single signal in the view which passes the string of
which page to go to would be better than having 6 signals?
MenuSignal(String)</p>
<p>Also if I do it that way wouldn't I it make more sense then to
just bypass the views mediator and let the root mediator handle the
change of content as there would be nothing for the views mediator
to do and if we do bounce the command again in the views mediator
isnt that just extra work for no reason?</p>
<p>Here's what I got.... So it's flow is:</p>
<p>root context > startup > view (stage view) > stage
mediator (potentially skip?) > root context mapped signal >
command to take injected views and update depending on which
section name is given.</p>
<p>I know this ia s lot to look at... Is that correct?</p>
<p>rootContext.as<br>
// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #<br>
// Map the model singletons injector.mapSingleton(ConfigModel);<br>
injector.mapSingleton(HomePageModel);<br>
injector.mapSingleton(LanguageModel);<br>
injector.mapSingleton(MainMenuModel);<br>
injector.mapSingleton(MainMenuPopupsModel);<br>
injector.mapSingleton(NavigationModel);<br>
injector.mapSingleton(PagesModel);<br>
injector.mapSingleton(QuickMenuModel);<br>
injector.mapSingleton(RemoteControlModel);</p>
<p>// TODO: Need to popuplate the models with xml data before app
run</p>
<p>// map the signals
injector.mapSingleton(UpdateDisplaySignal);</p>
<p>// Add to stage sequence var stageView:StageView = new
StageView();<br>
contextView.addChild(stageView);</p>
<p>// map the views to their mediators
mediatorMap.mapView(StageView, StageMediator);</p>
<p>//map events - startup complete
commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE,
StartUpCommand);</p>
<p>// A startup signal is created in order to call the
StartupCommand var startupSignal:Signal = new Signal();<br>
signalCommandMap.mapSignal(startupSignal, StartUpCommand);<br>
startupSignal.dispatch();</p>
<p>StartUpCommand.as - is empty<br>
// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #</p>
<p>UserInterfaceMediator.as<br>
// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #<br>
override public function onRegister():void<br>
{</p>
<pre>
<code>trace("StageMediator.onRegister()");
view.init();</code>
</pre>
<p>}</p>
<p>UserInterfarceView.as<br>
// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #<br>
private var mcUserInterface:FLAmcUserInterface;<br>
private var menu:MovieClip;</p>
<p>private var mainMenu:MainMenu;<br>
private var menuSelectionSignal:Signal;</p>
<p>public function StageView(){ trace("StageView()"); }</p>
<p>public function init():void<br>
{</p>
<pre>
<code>trace("StageView.init()");
// Setup main UI asset
mcUserInterface = new FLAmcUserInterface();
addChild(mcUserInterface);
// Clear container contents (it has a locator shape in it from the FLA visual positioning)
mcUserInterface.FLAmcVirtualWorldContainer.graphics.clear();
new RemoveAllChildrenIn(mcUserInterface.FLAmcVirtualWorldContainer);
// Map menu and menu options
mainMenu = new MainMenu(mcUserInterface);
mainMenu.x = 465; mainMenu.y = 26;
//new DebugPosition2D(Variables.stage,mainMenu);
addChild(mainMenu);
// Define menu selection signal
// String will be which menu option has been selected for root context to work out what to fade in & out (instead of having 6 signals)
menuSelectionSignal = new Signal(String);
// Define names & listeners
mainMenu.menuOptionResources.addEventListener(MouseEvent.CLICK,clickHandler);
mainMenu.menuOptionWhitePapers.addEventListener(MouseEvent.CLICK,clickHandler);
mainMenu.menuOptionCaseStudies.addEventListener(MouseEvent.CLICK,clickHandler);
mainMenu.menuOptionContactUs.addEventListener(MouseEvent.CLICK,clickHandler);
mainMenu.menuOptionShare.addEventListener(MouseEvent.CLICK,clickHandler);</code>
</pre>
<p>}</p>
<p>private function clickHandler(e:MouseEvent):void<br>
{</p>
<pre>
<code>trace("StageView.clickHandler(): name = " + e.target.name);
// Get targets name for signal to process the targets name
var clickedName:String = e.target.name;
menuSelectionSignal.dispatch(clickedName);</code>
</pre>
<p>}</p></div>actimel76tag:robotlegs.tenderapp.com,2009-10-18:Comment/145128562012-04-17T01:08:57Z2012-04-27T07:52:58ZMediator dispatches on mapListner to view but not on elements within the view<div><p>The mediator's job is to relay info to and from the view. So,
although it may seem like a short cut to have a "root" mediator
that handles it all, you will eventually create dependancies that
will limit your code re-use and will end up with spaghetti code,
which defeats the purpose of using MVC.</p>
<p>The extra time spent de-coupling your app will save you
countless hours debugging intertwined code. If each actor has
clearly defined tasks, when something breaks you can isolate the
culprit easily :)</p>
<p>Cheers,</p>
<p>J.</p></div>Jerome Maurey-Delaunay