tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/842-eventdispatcherextension-injection-of-event-dispatcher-into-model-and-the-role-of-commandsRobotlegs: Discussion 2013-03-11T13:40:18Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-20T11:01:05Z2013-02-20T11:01:06ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Hey,</p>
<p>I'm a newbie in MVCS/Command pattern/Robotlegs area. I'm trying
to understand how this framework works and what would be the best
way to use it in a average-size project. My priority is to keep the
code transparent. Usually my apps end up as huge chaotic webs of
dependencies and it's nearly impossible to understand what is going
on in the code.</p>
<p>So here is how I create the context:</p>
<pre>
<code>_context = new Context()
.install(
TraceLoggingExtension,
VigilanceExtension,
InjectableLoggerExtension,
ContextViewExtension,
EventDispatcherExtension,
ModularityExtension,
CommandCenterExtension,
EventCommandMapExtension,
LocalEventMapExtension,
ViewManagerExtension,
StageObserverExtension,
ManualStageObserverExtension,
MediatorMapExtension,
StageCrawlerExtension,
StageSyncExtension)
.configure(ContextViewListenerConfig)
.configure(BasicDemoConfig)
.configure(new ContextView(this));</code>
</pre>
<p>I just install extensions from MVCS Bundle plus my
BasicDemoConfig.<br>
Now, in my config.configure() method I do this:<br>
<code>injector.map(MainItemModel).asSingleton();</code></p>
<p>MainItemModel is a simple class not extending or implementing
any other class. I am able to [Inject] IEventDispatcher into it,
but if I try to use it inside the constructor, the dispatcher is
null:<br></p>
<pre>
<code>public function MainItemModel() {
dispatcher.addEventListener(MyBasicEvent.STH_HAPPENED, sthHappenedHandler);
}</code>
</pre>
<p>Why did I want to inject EventDispatcher into model? At first
I've tried to use commands to do all the work. My idea was to make
commands manipulate models, view (or mediators) directly. It failed
as I wasn't able to inject views into commands:<br>
<code>Injector is missing a mapping to handle injection into
property</code></p>
<p>I was only able to inject events and models into command, so I
thought I could let go of commands completely, and handle all
communication with shared IEventDispatcher. But as stated above, I
don't know how to access dispatcher in Model class.</p>
<p>Am I injecting EventDispatcher into model correctly? In my app
there's a mediator with IEventDispatcher injected and it uses the
dispatcher before I get the error in my model. So in the mediator,
the IEventDispatcher is instantiated but in the model it's not - is
it not the same instance?<br>
Is my idea of writing application without commands a good idea? Am
I correct that commands are only able to manipulate on Model?</p></div>kihutag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-20T13:19:15Z2013-02-20T13:19:15ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Hi kihu,</p>
<p>I don’t have enough time right now to get into details and
answer all your questions, so I’ll just give you the solution
to your constructor issue.</p>
<p><a href=
"https://github.com/robotlegs/robotlegs-framework/wiki/common-problems#wiki-null-in-constructor">
https://github.com/robotlegs/robotlegs-framework/wiki/common-proble...</a></p>
<p>Use [PostConstruct] metadata to let the injector invoke a method
of your class after all injections have been applied:</p>
<pre>
<code>[Inject]
public var eventDispatcher:IEventDispatcher;
public function SomeClass()
{
}
[PostConstruct]
public function someMethod():void
{
eventDispatcher.addEventListener(SomeEvent.SOME_TYPE, onSomethingHappened)
}
private function onSomethingHappened (event: SomeEvent):void
{
//do something
}</code>
</pre>
<p>I hope this helps at least a little bit :)</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-20T13:23:30Z2013-02-20T14:42:52ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Thank you! I'll try this.</p>
<p>Meanwhile, I've been told that adding listeners to model is not
a good practice. Still have to learn much theory, I guess.</p>
<p>Thanks again:)</p></div>kihutag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-21T08:53:14Z2013-02-21T08:53:14ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Or you could inject the eventdispatcher as a constructor
parameter if you need to dispatch an event immediately. However,
I'd only do this when there's no other possibility and use Ondina's
solution.</p>
<pre>
<code>public function MainItemModel( dispatcher : IEventDispatcher ) {
eventDispatcher = dispatcher;
}
private var eventDispatcher : IEventDispatcher;</code>
</pre></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-22T07:04:58Z2013-02-22T07:04:58ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Ah, I only just saw</p>
<blockquote>
<p>I've been told that adding listeners to model is not a good
practice. Still have to learn much theory, I guess.</p>
</blockquote>
<p>Not sure why anybody would give that advice though. Listening to
model events is common practice.</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-22T09:17:44Z2013-02-22T09:17:47ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Hey, creyders, thanks for the advice. I went with Odina's
[PostConstruct] solution and it worked. As for Model events I meant
adding listeners to Model, so receiving - not dispatching
events.</p>
<p>It's criticized in Robotlegs "best practices" wiki:</p>
<p><a href=
"https://github.com/robotlegs/robotlegs-framework/wiki/Best-Practices#wiki-Models">
https://github.com/robotlegs/robotlegs-framework/wiki/Best-Practice...</a></p>
<pre>
<code>Listening for Framework Events in a Model
While this is technically possible it is highly discouraged. Don’t do it. Just for the sake of clarity: Don’t do it. If you do, don’t say you weren’t warned</code>
</pre></div>kihutag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-22T17:19:55Z2013-02-22T17:19:55ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Hey kihu,</p>
<p>You’re right: Listening for Framework Events in a Model or
Service is not a recommended MVCS practice. Camille would agree
100% on this;) He just misunderstood your question.</p>
<blockquote>
<p>Is my idea of writing application without commands a good
idea?</p>
</blockquote>
<p>Not really:) I think commands are very useful and nice (they get
gc-ed right after execution!!)<br>
Without commands it is much harder to keep the 4 tiers (MVCS)
decoupled.</p>
<blockquote>
<p>Am I correct that commands are only able to manipulate on
Model?</p>
</blockquote>
<p>Nope. Commands can also call methods on Services. They can
actually do whatever you want them to do. Bootstrapping, mappings,
clean your shoes.. ;)</p>
<p>You mentioned the Best Practices in your last post. There
you’ll find a chapter about commands too.</p>
<p>Do you need more links to tutorials or examples, or did you find
them already?</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-24T11:41:42Z2013-02-24T11:41:42ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>@kihu ah, ok I misunderstood. You're right, letting a model
listen directly to events is a very bad idea.</p>
<p>About the commands: what @Ondina said. And I understand the
hesitation, but commands should actually be the "glue" between the
different parts. You should aim to make your models, services and
views as independent from each other as possible (it all depends
though, but let's take it as a general rule for the moment) but
obviously, somehow the various parts need to be patched together,
that's what your commands do. They're the dirty workers. They
configure, wire and call the methods of your MVS parts. So, in
fact, they're allowed to do "anything". Personally I hardly ever
use commands for my view-tier, but that's definitely also a
possibility, to let them create view instances and pass them to the
correct display object containers (through mediators) for
instance.</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-26T14:03:02Z2013-02-26T14:52:35ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Hey, thank you guys for help! To be honest I was a little
worried I'd be laughed at for being such an ignorant. Instead I've
got some solid advice:)</p>
<p>After a week of building an app with RL2 I feel a little more
comfortable with the architeture, still a long way to 'pro' level,
though. I've been using commands to operate on Model and then I
dispatcher.dispatchEvent to the whole framework. Every relevant
mediator has IEventDispatcher injected.</p>
<p>If I want to send some events between Mediators, I rely on this
injected IEventDispatcher. Only if I want to change something in
Model, I use Commands.</p>
<p>Example:<br></p>
<pre>
<code>User clicks button in View -> Mediator sends Event ->
mapped Command is executed -> this Command manipulates Model ->
Model dispatches another Event -> some Mediator listens to this other Event and reacts</code>
</pre>
<p>creynders: you wrote you sometimes manipulate views inside your
Commands. If example above had mediators accessible in Commands, it
would look like this:<br></p>
<pre>
<code>User clicks button in View -> Mediator sends Event -> mapped Command is executed
-> this Command manipulates Model and View/Mediator</code>
</pre>
I think the Model and View Layers are still independent in this
scenario. Hmm, but now I see the first approach might be better in
terms of clarity...
<p>Well, I still need to think these matters through.</p>
<blockquote>
<p>Do you need more links to tutorials or examples, or did you find
them already?</p>
</blockquote>
<p>I've been reading readme files on GitHub and some examples found
on the forum, but since you ask, could you point me to some
materials about 'behaviors'?</p>
<p>Thanks</p></div>kihutag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-02-26T15:13:22Z2013-02-26T15:13:22ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Hi kihu,</p>
<p>I’m glad we didn’t scare you off ;)</p>
<blockquote>
<p>Every relevant mediator has IEventDispatcher injected.</p>
</blockquote>
<p>You don’t need to do this for a non-modular app. Mediators
have access to the default event dispatcher:<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/bundles/mvcs/Mediator.as#L30">
https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<blockquote>
<p>User clicks button in View -> Mediator sends Event ->
mapped Command is executed -> this Command manipulates Model
-><br>
Model dispatches another Event -> some Mediator listens to this
other Event and reacts</p>
</blockquote>
<p>Yep, you got it!</p>
<blockquote>
<p>I've been reading readme files on GitHub and some examples found
on the forum, but since you ask, could you point me to some
materials about 'behaviors'?</p>
</blockquote>
<p>Hmm, I’m afraid I don’t know where to find that.
Maybe Camille or someone else can help you with this.</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/251228592013-03-11T13:40:17Z2013-03-11T13:40:17ZEventDispatcherExtension, injection of event dispatcher into Model and the role of commands<div><p>Kihu, I'm closing this discussion, but feel free to reopen it if
you need to.</p></div>Ondina D.F.