tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/887-hidden-mediated-viewstack-views-being-corrupted-on-event-handleRobotlegs: Discussion 2012-06-29T09:05:09Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-25T07:26:50Z2012-04-25T07:26:50ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>Hey Justin,</p>
<blockquote>
<p>instances are included/excluded via flex states</p>
</blockquote>
<p>I think the Flex States are the problem. Views get removed from
the display list and added again when the state changes. When Views
are removed from the display list, their Mediators are removed as
well, and then created again when their Views are added to the
display list.</p>
<p>If you take a look at the parameters of the mediatorMap.mapView,
you can see that autoCreate and autoRemove are by default set to
true.<br>
mediatorMap.mapView( viewClassOrName, mediatorClass, injectViewAs,
autoCreate, autoRemove );<br>
You can change that, for example you can set autoCreate to true and
autoRemove to false.<br>
In this case you will have to remove the Mediators manually, if
need be.</p>
<p>Is it possible that you are triggering some actions in your
onRegister() , maybe a service call?</p>
<p>Can you show us some stripped down code that shows the issue or
even attach the app or a simplified example? I am willing to take a
look at it. At least the code of a mediator on Register() ?</p>
<p>Cheers,<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-25T07:55:56Z2012-04-25T07:55:56ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>Another thought related to the Flex States and the
Views/Mediators creation and destruction:<br>
I think that your Views and Mediators don’t get garbage
collected for some reason (strong references of some kind), and
that can cause memory leaks. You’ll have to make sure
you’re removing all strong references to objects and event
listeners.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-25T07:58:27Z2012-04-25T07:58:27ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>Ondina,</p>
<p>Thanks so much for the reply.</p>
<p>Funny you should mention the onRegister method. I saw some other
posts regarding making service calls from this method and how it
could be a bad idea. I definitely make calls to initialize the view
in onRegister; however, I believe I am handling them in a
null-safe, life-cycle safe manner in the mediator and view. In
fact, the init events and any updates from other views flow through
the same event handling and ui update path.</p>
<p>Do you know of any known issues with the onRegister, init calls,
and viewstacks?</p>
<p>I could understand a NPE or RuntimeException, but the view
corruption is just unsettling. On one occasion, I did see a script
timeout exception. This could indicate some infinite (or very deep)
bind/validation loop in the depths of flex.</p>
<p>One last little nugget. In my debugging, I saw a mediator get
disposed and another immediately get assigned on the same view
instance (i.e. same memory addr). I know RL will do a little
optimization if it was within the same frame, but this must have
spanned a frame in this case. In any event, I still think my code
should handle this gracefully (albeit inefficiently).</p>
<p>If none of these avenues lead towards an answer, I can
definitely look into simplifying the view logic and sending you the
basics of what I'm trying to do. Sorry for the fire-hose of
details. Didn't want to leave anything out.</p>
<p>Thanks again for the help. These boards never disappoint,<br>
Justin</p></div>Justintag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-25T08:20:19Z2012-04-25T08:20:19ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>Ondina,</p>
<p>Re: GC and Listener clean-up:<br>
I am using the eventMap's map/unmap methods (with the defaults for
capture, weakReference, ext) to manage my listeners. This is the
correct approach for managing in RL correct?</p>
<p>It definitely appears that Flex is caching my view for
performance reasons.</p>
<p>I may just have to roll my own viewstack with states and
basiclayout to see if the problem is with that old container. No
doubt I am pushing the limits with ViewStack, states,
visible/includeInLayout. Oh and of course the views themselves are
complex with many custom item renderers, etc. ;)</p>
<p>Thanks again for the info. Heading offline for a bit of
recovery, but will be back soon.</p></div>Justintag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-25T08:35:45Z2012-04-25T08:35:45ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>You’re welcome, Justin:)</p>
<p>I’ll try to address your questions later on today. Of
course it would be better/easier (for me) to see the code. In case
you don’t want to post your code publicly, I could make the
thread private (you can do that too), so you can attach your app,
and after I download the file I would delete it and make the
discussion public again.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-25T15:37:17Z2012-04-25T15:37:17ZHidden, mediated ViewStack Views being corrupted on event handle<div><blockquote>
<p>Funny you should mention the onRegister method. I saw some other
posts regarding making service calls from this method and how it
could be a bad idea.</p>
</blockquote>
<p>The idea is to avoid having view logic in your Mediator, to
avoid holding state, and to let it be just a bridge between Views
and the rest of the application.<br>
But, I don’t think it’s a bad idea per se to dispatch
an event from the Mediator’s onRegister() –to let other
Mediators do something in response to it, or to trigger a command
in order to set something on a Model or to call a Service.<br>
I guess, the discussions you saw were about accessing Models and
Services directly from Mediators. Is it a good or a bad practice?
There are many different opinions about this topic.<br>
Personally, I don’t inject Services into my Mediators, and
whenever I can, I avoid injecting Models as well. And when I inject
Models, I use interfaces. I keep my Mediators light and as free of
logic as even possible. I’m a proponent of following the best
practices, but I’m certainly not a purist.<br>
For example, I think that strictly loose coupling is not always
achievable or even desirable.<br>
Following a standard way of doing things has many advantages, of
course, and in my opinion, it’s an easy thing to do,
actually. A lot more difficult is to decide what’s
“best” in a certain context – there is a
so-called “contextual practice” or “context
driven development”. But I digress ;)</p>
<p>After being added to the display list a View may need data from
external resources right away.<br>
If you’d take a purist approach, you’d let the View
(Component) dispatch an event whenever it needed data (in this case
after it has been added to the stage), and its Mediator listening
for that event would <em>just</em> relay it to the rest of your
application, and when the data returns, the Mediator would pass it
to its View.<br>
But the rl-Mediators get created in response to Views being added
to the display list.<br>
onRegister() == View has been added to the display list already,
and its sub-components’ creationComplete has fired.<br>
If you wouldn’t have to care about the sub-components,
dispatching an additional event from the View upon its creation, to
let the Mediator know that it needed data, would be an unnecessary
extra step, in my opinion. You could do that within the
onRegister() of the Mediator.</p>
<p>But, usually, you would want to make a service call in order to
get some data for the Views’ sub-components, i.e. data
providers for lists, datagrids…so, you’d have to be
aware of their life cycle and their readiness for receiving
data.</p>
<p>Using bindings and item renderers makes it even more
complicated. Triggering a service call from the Mediator’s
onRegister can be tricky due to the asynchronous nature of the
responses. You can not know whether the data returns before or
after the sub-components, especially complex ones, are ready to set
their data providers. Item renderers are known for being
problematic in this regard.<br>
Calling a service through an event dispatched from onRegister is ok
(in my opinion), but it’s up to you to decide whether
it’s a safe thing to do or if you have to wait until all
sub-components have been fully initialized, created, added to stage
and layed out.</p>
<p>Do you need to make a service call every time the View gets
added to the stage? If you needed it just the first time, then
every other call would be superfluous and a possible cause of
trouble.</p>
<blockquote>
<p>I am using the eventMap's map/unmap methods (with the defaults
for capture, weakReference, ext) to manage my listeners. This is
the correct approach for managing in RL correct?</p>
</blockquote>
<p>Correct, but usually, you don’t need to unmap the
listeners manually. If there are no strong references to an object
(for example adding listeners to views directly, instead of using
the event map can lead to strong references) the listeners get
automatically unmapped when the mediator runs its onRemove() method
(autoRemove=true).</p>
<blockquote>
<p>I may just have to roll my own viewstack with states and
basiclayout to see if the problem is with that old container. No
doubt I am pushing the limits with ViewStack, states,
visible/includeInLayout. Oh and of course the views themselves are
complex with many custom item renderers, etc. ;)</p>
</blockquote>
<p>Yes, I think it’s a good idea to start with a simplified
ViewStack and add features gradually.<br>
Changing states, setting visible, using includeInLayout, and
complex item renderers as well can be problematic even without a
framework ;)</p>
<p>Let us know how it goes.</p>
<p>Ah, I almost forgot. In case you’re using FlashBuilder,
have you tried to run the profiler and let it find loitering
objects?</p>
<p>Hmm, long rant and I don’t even know if I answered all
your questions.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-26T07:36:18Z2012-04-26T07:36:18ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>Ondina,</p>
<p>I appreciate the long rant ;) I'm always interested in hearing
everyone's opinions in the UI space. So many more options than just
beans, crud, etc. in the middle tier.</p>
<p>Speaking of the middle tier, that's where I've been so I haven't
had much time to simplify my view and see if that helps my problem.
I plan to tackle that in the coming hours so I will keep the board
up-to-date. Unfortunately, the app and views are too complex to
build, run, or even upload so I'm going to have to do the
simplification step on my own. I really appreciate the offer to
look through the code directly. I'm sure I'll be hitting up the
boards with my findings tomorrow.</p>
<p>Thanks for the tip on auto-removing listeners. I've been
cleaning them up manually in the onRemove method. That saves me
some code and some copy/paste errors of re-mapping in onRemove.</p>
<p>As for onRegister and decoupling purity, I couldn't agree more
with everything you said. I don't inject models/services, but I do
issue data request events. The extra step of dispatching from the
view is where my pragmatism overrides my quest for purity.</p>
<p>creynders did mention Stray's relaxed eventmap, but, while it
looked cool, it seemed like too much setup and ramp-up cost for my
needs. The discussion board closed before I could thank him for the
suggestion.</p>
<p>But now I'm ranting! Thanks again and I'll keep everyone
up-to-date.</p>
<p>Thanks again,<br>
Justin</p></div>Justintag:robotlegs.tenderapp.com,2009-10-18:Comment/155328532012-04-26T07:57:16Z2012-04-26T07:57:16ZHidden, mediated ViewStack Views being corrupted on event handle<div><p>Hey Justin,</p>
<blockquote>
<p>creynders did mention Stray's relaxed eventmap, but, while it
looked cool, it seemed like too much setup and ramp-up cost for my
needs. The discussion board closed before I could thank him for the
suggestion.</p>
</blockquote>
<p>I re-opened it, so you can thank him:)<br>
(Actually, as the author of the thread you should be able to
re-open a closed discussion as well, as far as I know)</p>
<blockquote>
<p>Thanks again and I'll keep everyone up-to-date.</p>
</blockquote>
<p>My pleasure! Looking forward to your feed-back:)<br>
Cheers,<br>
Ondina</p></div>Ondina D.F.