tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/322-request-model-form-mediator-mechanismRobotlegs: Discussion 2018-10-18T16:35:27Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/73806202011-05-22T14:04:40Z2011-05-22T14:04:40ZRequest model form mediator mechanism<div><p>Hi Maarten,</p>
<p>The 'don't inject models and services into your mediators'
advice is based on a few things, and I'm not sure your situation
matches that.</p>
<p>I don't think your 'model' is a model. It's really more like a
configuration - yes? As in, its state doesn't change after run
time, and it has no writable-api?</p>
<p>The reason we advise avoiding injecting models into mediators is
about avoiding ending up with complex logic in your mediator -
there are numerous reasons why that can end up getting messy very
fast, to do with race conditions, the fact that the mediator isn't
stateful (each instance is destroyed and a new one created when a
view comes and goes from the stage) and you can wind up with a lot
of duplication.</p>
<p>In addition, mediator injections are prone to suffering from
race conditions - if your view hits the stage before your config
has loaded then the injection can't be fulfilled yet and you'll get
a null error if it hasn't been mapped, or null values if the data
in that model isn't yet populated. Yuk.</p>
<p>So - if your settings VO isn't really stateful - just a config -
and if you're certain it will be available before these mediators
are created - I think it's reasonable to inject it - though still
not ideal. If you do want to inject it and it has a writable-api
then I would inject it against a read-only API.</p>
<p>The other option is to use a request/response pattern. As you
say - the trouble with request/response events is that you wind up
with every listener responding to every response.</p>
<p>The simplest solution in this situation is to pass a callback to
be used to return the variable on the request event.</p>
<p>Alternatively you can do it with AS3 signals, which gives you
more intelligent error checking (at runtime). If you're familiar
with signals and you want to do it this way, shout and I'll give
you a code example. If you're not familiar with signals then go
with injection or passing a callback on your requestEvent.</p>
<p>I hope that helps,</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/73806202011-05-22T14:44:44Z2011-05-22T14:44:47ZRequest model form mediator mechanism<div><p>Thanks Stray, I understand what you are telling me. The thing is
that the settings model is statefull. I have a setting view, where
the user can configure program settings...</p>
<p>So I guess it would be cleaner if I go with the request/response
pattern for the settings. The fact that every listener will catch
the events, is a problem. I'm just learning robotlegs, so for this
project I'm not yet going to dig into the signals thing... I put it
on my todo list :)</p>
<p>But what do you exactly mean bij passing a callback to the
request event? Passing a reference to a callbackfunction on the
mediator? That sounds odd :)</p>
<p>One more thing. I use the application model (model of
contextview) to store those application wide config settings.
Examples: currentlanguage, currentpage , pagehistory, firstrun,
currentversion . I guess this a valid strategy?</p>
<p>Thanks for helping ... I have some other questions, but I'll
start a new topic later on :)</p></div>Maartentag:robotlegs.tenderapp.com,2009-10-18:Comment/73806202011-05-22T15:03:04Z2011-05-22T15:03:04ZRequest model form mediator mechanism<div><p>Hi Maarten,</p>
<p>ah - yes, sounds like a model and not a config then :)</p>
<p>So - the code for what I was describing would look like
this:</p>
<pre>
<code>// the request event takes a handler as its payload
public function RequestSettingsEvent(eventType:String, responseHandler:Function, etc...)
// the mediator dispatches its local handler as this payload
public function onRegister():void
{
dispatch(new RequestSettingsEvent(RequestSettingsEvent.SETTINGS_REQUESTED, receiveSettings));
addContextListener(SettingsChangeEvent(SETTINGS_CHANGED, settingsChangedHandler));
}
protected function settingsChangedHandler(e:SettingsChangeEvent):void
{
receiveSettings(e.vo);
}
protected function receiveSettings(settingsVO:ISettingsVO):void
{
// do whatever is needed with the settings
}
// the command that handles the request
[Inject]
public var requestEvent:RequestSettingsEvent;
[Inject]
public var settingsModel:ISettings;
public function execute():void
{
var vo:ISettingsVO = settingsModel.getVO();
requestEvent.responseHandler(vo);
}</code>
</pre>
<p>Anyway - the way you have suggested will work too - really they
are the same thing, it's only that this approach is less work at
runtime (for the program) because you're not having a bunch of
mediators run their handler and then execute.</p>
<p>Either approach is good I think,</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/73806202011-05-23T08:01:45Z2011-05-23T08:01:47ZRequest model form mediator mechanism<div><p>Thanks stray, great explanation.</p>
<p>I think you solution is better than mine. I'll do it by using a
callback function in the command.</p>
<p>Maarten</p></div>Maarten