tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/39-possible-bug-with-mediator-when-using-flex-statesRobotlegs: Discussion 2018-10-18T16:35:08Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T05:26:27Z2010-01-27T05:26:27ZPossible Bug with Mediator when using Flex States<div><p>My reply is more of a question than an answer so please forgive
me.</p>
<p>I was thinking that in your context, you could try the
following. Will <code>injector.mapSingleton()</code> work to
satisfy your request? Anyone from the RL crew? I'm drawing straws
as it's late and this was the first thing that came to
mind.<br></p>
<pre>
<code> override public function startup():void {
// Map Views
injector.mapSingleton(ViewState1);
mediatorMap.mapView(ViewState1, ViewState1Mediator);
mediatorMap.mapView(ViewState2, ViewState2Mediator);
dispatchEvent(new ContextEvent(ContextEvent.STARTUP_COMPLETE));
}</code>
</pre></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T06:20:30Z2010-01-27T06:20:36ZPossible Bug with Mediator when using Flex States<div><p>Phil. Just playing around quickly, I've found that in the
MediatorMap Class of RB, it will call createMediator under certain
conditions.</p>
<p>If you turn off the autoCreate (which in your case i believe is
acceptable since your defining the mediator), you won't have the
constructor called every time. (assuming I recall the purpose of
autoCreate correctly).</p>
<p>Try this out, seems to trace out fine here.</p>
<p>mediatorMap.mapView(ViewState1, ViewState1Mediator, null,
false);<br>
mediatorMap.mapView(ViewState2, ViewState2Mediator, null,
false);</p>
<p>Hope that helps your project :D</p></div>darrentag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T11:04:40Z2010-01-27T11:04:40ZPossible Bug with Mediator when using Flex States<div><p>Hi Phil,</p>
<p>you should probably turn off autoRemove when mapping your
views.</p>
<p>As Darren wrote, you can also turn off autoCreate, but in your
case,<br>
you'd probably want the mediator to get created the first time a
view<br>
is activated through a state change. So, modifying Darrens
example,<br>
your code could look like the following:</p>
<p>mediatorMap.mapView(ViewState1, ViewState1Mediator, null, true,
false);<br>
mediatorMap.mapView(ViewState2, ViewState2Mediator, null, true,
false);</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T11:06:46Z2010-01-27T11:06:46ZPossible Bug with Mediator when using Flex States<div><p>Hi Phil,</p>
<p>Automatic mediator registration works by listening for
ADDED_TO_STAGE events on the contextView - it's the only way we can
find out the scope of the view component. Changing states causes
the views associated with those states to be added/removed from the
display list, in turn registering/removing the mediators.</p>
<p>This is actually the expected behavior. Even though the view
components are only constructed once, when they are removed from
stage we can no longer consider them inside the scope of the
contextView - when a view component is removed from the display
list we have no guarantee that it will be added back to the display
list in the same scope (it might be added somewhere else, inside a
different scope/context).</p>
<p>@levi - unfortunately, the singleton mapping will be overridden
by a temporary mapping in the MediatorMap when the mediator is
created, and hence lost.</p>
<p>@darren - manual registration/removal is indeed the solution
here, but I would recommend leaving autoCreate on and turning
autoRemove off, like so:</p>
<pre>
mediatorMap.mapView(ViewState1, ViewState1Mediator, null, true, false);
mediatorMap.mapView(ViewState2, ViewState2Mediator, null, true, false);
</pre>
<p>It's worth noting that it then becomes the developers
responsibility to remove the mediators when appropriate.</p>
<p>@phil A better approach might be to avoid mapping mediators to
view components that are toggled by state and to instead mediate
the view component that holds them. In your case, I would put
ViewState1 and ViewState2 inside another view component, and map a
mediator to that instead.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T16:20:51Z2010-01-27T16:20:56ZPossible Bug with Mediator when using Flex States<div><p>Thanks for the suggestions guys! I set autoRemove to false and
that seems to do the trick.</p>
<p>Shaun, thanks for the explanation of what's going on behind the
scenes. In terms of mapping one mediator to a view that contains
ViewState1 and ViewState2, personally, I think it makes more sense
to seperate the logic for ViewState1 and ViewState2 into seperate
mediators because they really are unrelated and so logic for each
should be decoupled.</p>
<p>I'd be interested to hear how other people are handling this
scenario because this type of thing occurs not only when you use
states, but any time you use navigators like Accordion, TabBar,
etc. Do you guys generally just set autoRemove to false?</p></div>Phil Chungtag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T16:48:47Z2010-01-27T16:48:47ZPossible Bug with Mediator when using Flex States<div><p>Hi Phil,</p>
<p>As far as I know Accordions, ViewStacks, Lists etc use deferred
instantiation - they don't actually remove things from the display
list, creation is simply deferred until needed - so everything
should work as expected.</p>
<p>Personally, I don't ever set autoRemove to false. I treat
mediators as temporary link-ups between the framework and
on-display view components. IE, I expect my mediators to exist only
while their view components are on-stage. I also expect to get a
new mediator instance when a view component is added to the stage
after previously having been removed.</p>
<p>If ViewState1 and ViewState2 are indeed totally unrelated, then
the current behavior seems desirable to me - each ViewState should
only be mediated while on-stage. I feel that perhaps your mediators
are stateful, or trigger off some kind of action on registration,
and hence cause undesirable side-effects. Could you provide some
more detail as to why you find the behavior undesirable?</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T17:32:45Z2010-01-27T17:32:50ZPossible Bug with Mediator when using Flex States<div><p>Shaun,</p>
<p>Thanks for taking the time to respond. Perhaps I misunderstood
the behavior of Mediators as I didn't realize they weren't
stateful, but your explanation makes sense.</p>
<p>So I'd like to ask how you would set up this scenario. I have 3
views, each displayed in a different Flex state. When each view is
first displayed, I need to make a call(s) on the service class and
listen for the event that tells the mediator that the data is
ready, and we can update the view. However, after that view is
displayed once, each subsequent time you display that view, we
don't want to repeat those calls on the service. The problem arose
for me because I was making the service calls and setting up to
listen for events in the onRegister of my Mediators.</p>
<p>It's sounding more to me like I need to set up
PresentationModels for my views, since that's not what Mediator is
meant for, but I'd still like your opinion, particularly on where
you think the service calls should be triggered.</p></div>Phil Chungtag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T19:35:27Z2010-01-27T19:35:27ZPossible Bug with Mediator when using Flex States<div><p>The initial service call can be a Command that is triggered by
an event (possibly the event that displays the view initially). The
Command will check the model, if the data is there, it will make
the service call. The service updates the Model via a separate
Command (or directly, I prefer to use Commands here). When the
model's data is updated it fires an event that the mediator(s)
listen for and know to update their view components with the new
data.</p>
<p>I <em>always</em> encapsulate service actions in Commands. That
is really what they are good for, those cross tier actions. Any
data that a service returns should be stored on the model, so a
mediator should listen for service events. Mediators will listen
for events from other mediators, models, and commands.</p>
<p>This would be a good addition to best practices documentation I
think...</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/9183252010-01-27T21:15:53Z2010-01-27T21:15:54ZPossible Bug with Mediator when using Flex States<div><p>Thanks for chiming in Joel. The way you explained is pretty
close to how I'd set it up, except that I was calling the command
(triggering the event) inside of the mediator. I'll move it outside
of the mediator as you suggest.</p>
<p>Initially my perspective on the mediator is that it's basically
code behind, and aside from the injection stuff, which is awesome,
it allows me to keep the code out of my views. Which is why I was
thrown off when new instances of mediator were being created for
the same view instance.</p>
<p>Overall though, I think the best practices doc is fantastic.
Lots of good info in there.</p></div>Phil Chung