tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/144-how-to-approach-view-command-service-viewRobotlegs: Discussion 2018-10-18T16:35:11Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-04-30T06:37:17Z2010-04-30T06:37:21Zhow to approach View->Command->Service->View<div><p>Yes, you can bundle multiple commands into one single event with
string constant identifiers mapped to each command. I normally do
this to keep class count as low as possible. Dawn framework tends
to enforce 1 notification class-to-1 command class mapping unlike
RobotLegs which allows you to simply map ANY event string to any
command. To avoid configuration and errors with string-matching,
I'd normally use a convention that simply allows you to list out
all the commands required by the application, and the utliity
simply finds a public [Inject]"event" variable of the Command,
match the event class type to a constant string of the event
logically like OpenFile/OpenFileCommand to 'EventClass.OPEN_FILE=
"OPEN_FILE"' or 'EventClass.OPEN_FILE = "EventClass.OPEN_FILE"'. If
the convention fails, I throw an error/warning.<br>
Example 1-liner to map all commands: @new
AutoWireCommands(commandMap).setupCommands(OpenFile, CloseFile,
JumpToCommand, etc.) ;@<br>
And example utility at: <a href=
"http://github.com/Glidias/SG-Camo-Collections/blob/master/src/sg/camoextras/robotlegs/utils/AutoWireCommands.as">
http://github.com/Glidias/SG-Camo-Collections/blob/master/src/sg/ca...</a></p>
<p>If you don't intend to have the value stored in the model but
just need to have a short-lived pingback result, the dispatched
event can contain a public variable with an empty value initially.
DIspatch the event through the event bus which triggers the
command. The command accesses the service, which upon retrieving
whatever returned values, supplies the payloaded short-lived result
value back to the event's returnResult payload public variable. So,
after dispatching the event, you can get the response back from the
event object itself instead of accessing the data remotely from
some model.</p>
<p>For example, in a mediator class:</p>
<p>bc. var transitionReq:TransitionModuleEvent = new
TransitionModuleEvent(TransitionModule.REQUEST);<br>
dispatch(transitionReq);<br>
if (transitionReq.payload) {<br>
// do something with payload }</p>
<p>Normally though, I'd try to avoid as much code-behind as
possible in mediators, depending on value objects and middle-tier
controllers/services to resolve value changes.</p></div>Glidiastag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-04-30T11:20:19Z2010-04-30T11:20:19Zhow to approach View->Command->Service->View<div><p>Hi Raed,</p>
<p>First off, I don't think it's a good idea to be triggering
commands directly from Views; this should be the job of the
Mediator instead.</p>
<p>If you want to cut down on the number of Commands; you could
consider injecting the Service directly into the Mediator.</p>
<p>Your Mediator will then listen for events from the View which
trigger the Service, and events from the Service (via the central /
framework EventDispatcher) which get pushed back through to the
view.</p>
<p>You could either go with one class for each Service (ie:
LoginService, ForgotPasswordService); or - if that will result in
too many Classes for you (you can never have enough Classes IMHO!)
you could switch on the eventType in the Mediator and then call a
method on your Service class.</p>
<p>Hope that helps?<br>
Jonny.<br></p></div>Jonny Reevestag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-04-30T13:49:12Z2010-04-30T13:49:12Zhow to approach View->Command->Service->View<div><p>Hi Raed,</p>
<p>My point of view is this: If it feels messy and un-scalable, it
probably is.</p>
<p>When dealing with transient data there is usually very little
point to the whole View -> ViewEvent -> Mediator ->
SystemEvent -> Command -> Service -> ServiceEvent ->
Mediator -> View work-flow. That flow is useful for data and
events that many parts of the system want to know about (or may
want to know about in the future).</p>
<p>There are times when it makes much more sense to simply inject a
Service directly into a Mediator and call it from there. The
exposed Service method might even accept a callback so that it can
respond directly to the caller. I use the concept of "Promises" in
such situations, which look something like this:</p>
<pre>
remoteService.get('/users/' + userId)
.addResultHandler(onUserResult)
.addFaultHandler(onUserFault);
</pre>
<p>In this case I need to load a User object from the server so
that I can display it in a view. No other part of the system cares
about this - I'm not putting that User into a model, or saving it
for later, or anything like that. The Service is responsible for
translating the servers result into a format that the system
understands (in my case translating a JSON string into a bindable
AS3 object).</p>
<p>What I'm getting at is that Robotlegs shouldn't be getting in
your way. The Best Practices document outlines some good work-flows
for dealing with common scenarios, and it's a great starting point,
but once you understand the underlying principals it's up to you to
decide how appropriate the work-flows are for your particular
problems.</p>
<p>Getting back to your example, you could indeed get away with
having one Mediator for a View component with 3 states. The
Mediator could invoke service calls directly and pass the results
straight to the view.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-04-30T14:35:50Z2010-04-30T14:35:51Zhow to approach View->Command->Service->View<div><p>@Jonny, yes things always go trough their mediators. Injecting
the service into the Mediator sounds good, but i like how the
Context offers somewhat of a top level view of the application
wiring, and this would hide that away. but maybe i dont know to
know about every possible user gesture in this top level view and
just be satisfied with the presence of LoginService and
LoginViewMediator. (It would be so awesome if RL+some eclipse
plugin can study the Context and generate a block diagram :) )</p>
<p>@ Glidias. That Autowire utility looks really nice. but feels
risky. Ill look into it some more.</p>
<p>@Shaun/Jonny. Yes, after all Mediators are actors and it makes
perfect sense. Callbacks/Promise is making the most amount of sense
to me</p>
<p>The Best Practices is the first thing i read and it is really
excellent.</p>
<p>thank you so much for the feedback! Yay Community support.<br>
we can close this now</p></div>Raed Atouitag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-12-23T18:16:04Z2010-12-23T18:16:04Zhow to approach View->Command->Service->View<div><p>"First off, I don't think it's a good idea to be triggering
commands directly from Views; this should be the job of the
Mediator instead."</p>
<p>Is it ok for commands to act on injected meditators? or is it ok
to inject the view into the command and perform work on the view
that way?</p></div>Nikos tag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-12-23T19:27:45Z2010-12-23T19:27:45Zhow to approach View->Command->Service->View<div><p>It's "Ok" to do pretty much anything.</p>
<p>It's ideal to keep your view layer entirely separate from your
application layer. Which means not injecting mediators into
commands (your mediators should have no API anyway - they should
only respond to events / signals). Other than the contextView, I
wouldn't inject any view into a command.</p>
<p>Work on the view should stay in the view. Application logic
should stay in the application. Mediators dispatch and receive
events and signals to join the two together.</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-12-23T22:39:33Z2010-12-23T22:39:33Zhow to approach View->Command->Service->View<div><p>I see, How does one grab a hold of a specific mediator, since
they are created automatically?</p>
<p>I think I should listen to a signal dispatched from a command
instead, how do I do that?</p></div>Nikos tag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-12-24T20:44:24Z2010-12-24T20:44:24Zhow to approach View->Command->Service->View<div><p>@Nikos:</p>
<p>You could create a custom signal class and map that as a
singleton in your Context. This signal can now be injected into
both your Command and your Mediator. The Command would dispatch the
signal and your Mediator adds listeners to it to update its View
component accordingly.</p></div>Abel de Beertag:robotlegs.tenderapp.com,2009-10-18:Comment/15696292010-12-26T10:08:09Z2010-12-26T10:08:09Zhow to approach View->Command->Service->View<div><p>Thanks Abel thats exactly what I will do :)</p></div>Nikos