tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/2718-obtain-an-associated-mediator-from-a-view-objectRobotlegs: Discussion 2013-06-05T11:43:00Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/270799152013-05-30T16:08:25Z2013-05-30T16:08:52ZObtain an associated mediator from a view object<div><p>There are many ways to tackle this, but here is a pretty simple
solution.</p>
<p>Create an auto-incrementing static counter on your mediators
that will be used to generate unique <code>id</code>s. Supply this
when making service calls, and return it along with the results.
Then each mediator can just ignore messages that are not relevant
to it (where the <code>id</code> doesn't match).</p>
<pre>
<code>class MyMediator
private static var counter:int;
public const id:String = "id" + counter++;
private function serviceResultHandler(result):String
if (result.id != id) return;
...</code>
</pre>
<p>This assumes that the mediator is listening for service results
directly. If you want to differentiate the mediators in a command
you'd need to change things a little, but that's the basic
idea.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/270799152013-05-31T09:34:45Z2013-05-31T09:34:45ZObtain an associated mediator from a view object<div><p>According to the best practices of using Robotlegs, mediators
should not include any logic (that includes if-for-while ...).<br>
The solution you proposed includes logic in the mediator and
performs a broadcast (since all mediators are subscribed to that
event) and I'm worried about the efficiency.</p>
<p>You said that there are other solutions. Can you explain any
other that doesn't perform a broadcast calling?</p>
<p>Thank you for your answer.</p></div>victor.bolinchestag:robotlegs.tenderapp.com,2009-10-18:Comment/270799152013-05-31T14:08:23Z2013-05-31T14:08:23ZObtain an associated mediator from a view object<div><p>Hi Victor,</p>
<blockquote>
<p>According to the best practices of using Robotlegs, mediators
should not include any logic (that includes if-for-while ...).</p>
</blockquote>
<p>I think that's taking it a little too far. The idea is to avoid
putting "business logic" in your mediators. A mediator is supposed
to be a bridge between a view and the rest of the application. Part
of this role involves determining if a message from the application
relates to the view that is being mediated.</p>
<blockquote>
<p>and performs a broadcast</p>
</blockquote>
<p>The mediator is not broadcasting, it is subscribing to messages
from the app. This is what mediators are designed to do.</p>
<blockquote>
<p>I'm worried about the efficiency</p>
</blockquote>
<p>This would only be a real concern if you had a couple of hundred
thousand chat views. In reality, the performance impact would be
negligible for a few hundred views.</p>
<blockquote>
<p>You said that there are other solutions.</p>
</blockquote>
<p>Indeed! And the solution I proposed is my least favourite. I
only mentioned it because it's something you could implement
quickly with your current design.</p>
<p>Your initial question was actually how to "Obtain an associated
mediator from a view object"?</p>
<p>The framework does not provide a way to do this. Even if it did
it would be difficult to work with as a particular view might have
any number of mediators. One solution is to manually associate
views with mediators in a model. It's a similar approach to the one
above.</p>
<p>Essentially you create a model that allows you to associate
views with mediators. Mediators add themselves to this model in
their <code>initialize</code> method. The command can use this
model to retrieve mediators for views.</p>
<p>Psuedocode:</p>
<pre>
<code>
// Registered as a singleton
ChatViewModel
private const mediators:Dictionary = new Dictionary();
public function addMediator(mediator, view)
mediators[view] = mediator;
removeMediatorFor(view)
delete mediators[view];
getMediatorFor(view)
return mediators[view];
// In your mediator
[Inject]
public var view:PrivateChatView;
[Inject]
public var chatViewModel:ChatViewModel;
public function initialize():void
chatViewModel.addMediator(this, view)
// In your command
[Inject]
public var chatViewModel:ChatViewModel;
public function execute()
var view = event.view;
var mediator = chatViewModel.getMediatorFor(view)</code>
</pre>
<p>Again, this is just one solution.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/270799152013-05-31T14:16:17Z2013-05-31T14:16:17ZObtain an associated mediator from a view object<div><p>Thank you for explaining!</p></div>victor.bolinchestag:robotlegs.tenderapp.com,2009-10-18:Comment/270799152013-05-31T14:25:16Z2013-05-31T14:25:16ZObtain an associated mediator from a view object<div><p>My pleasure! As I said there are other approaches, but they
might require a complete redesign in terms of your service layer.
Personally, I use promises, instead of the awkwardly decoupled
<code>event->command->service->event->etc</code> flow.
See:</p>
<p><a href=
"https://github.com/CodeCatalyst/promise-as3">https://github.com/CodeCatalyst/promise-as3</a><br>
<a href=
"http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/">
http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/</a></p></div>Shaun Smith