tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/945-arraycollection-filterfunction-behavior-persisting-commandsRobotlegs: Discussion 2012-07-16T08:32:37Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/170428892012-07-02T20:38:46Z2012-07-02T20:38:46ZArrayCollection filterFunction behavior: persisting Commands?<div><p>[First off, I'm currently in the middle of a big
refactor-to-Robotlegs effort, and loving the framework - so thank
you already for this great resource!]</p>
<p>So I have a situation where I use a Command to define and then
assign a filterFunction to an arrayCollection in one of my data
Models. I put this in a Command because the filterFunction needs to
reference other models in the app (namely, complex data-selection
criteria in other Models). Then after calling refresh() on the
ArrayCollection, my ViewMediator picks up a "data refreshed" custom
event, and passes the filtered data Model to its View. So far so
good! But it gets better, unexpectedly (to me):</p>
<p>If I later refresh the data Model's ArrayCollection (either from
the ViewMediator, or from a different Command - doesn't matter),
the fitlerFunction still applies - and what's more, in debug mode I
can see it step into the filterFunction code in the Command in
which it's defined - even though a new instance of the Command
hasn't been invoked! Also, no need to send a refreshed version of
the Model from C to VM to V: it just magically updates correctly in
the view, wherever I call refresh() from.</p>
<p>This struck me as weird, given my current understanding of RL,
that 1) Commands do not persist after their execute() call, and 2)
Views are very decoupled from Models. My guess is that my adding a
reference to the Command instance (when I assign one of its
functions as the ArrayCollection's filter function) prevents the RL
framework from destroying the instance (like the FlashPlayer GC
works, not destroying instances with a positive reference count).
is that correct? And either way, is this in general a kosher way of
handling complex filterFunctions that need access to multiple
Models?</p>
<p>Thanks for any input.</p>
<p>Regards,<br>
-Peter</p></div>pdemlingtag:robotlegs.tenderapp.com,2009-10-18:Comment/170428892012-07-02T22:51:55Z2012-07-02T22:51:55ZArrayCollection filterFunction behavior: persisting Commands?<div><p>Hi Peter,</p>
<p>Yup, the filterFunction is keeping the command instance pinned
in memory - normal Flash Player GC stuff. Robotlegs releases all
internal references to commands after execution, but can't do
anything about references that it didn't create.</p>
<p>Personally, I don't mind the actual mechanics involved in your
setup - but I would move that stuff out of the command and into an
explicit persistent construct (like a service). Commands are
supposed to be fire-and-forget, and the fact that this particular
command persists is not being made clear. It doesn't reveal its
intent.</p>
<p>Hope that helps!</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/170428892012-07-03T13:19:24Z2012-07-03T13:19:24ZArrayCollection filterFunction behavior: persisting Commands?<div><p>Thanks for the reply, Shaun! That does clear things up.</p>
<p>I've struggled with the best place for locating the
filterFunction, since it needs to reference multiple
(data-selection) Models, and its complex churning feels like
business logic. That's why I initially went with Command; but I
agree that the lack of clarity on its quirky persistence is not
ideal. And I suppose injecting the (data-selection) Models into the
Service is preferable to injecting them into the data-storage Model
itself...</p>
<p>As to getting a M's ArrayCollection to update in a V: after a
one-time initialization of the V's instance by passing it in
through the VM, is it normal/expected to see it automatically
update, simply by calling refesh() on the M's ArrayCollection? I
had thought I would have to explicitly pass it down (M to VM to V)
on every update - but I'm seeing it happen without that effort.
Again, I'm assuming this is because I initialized the V's instance
with a reference to the M's instance; but I didn't know if this
kind of "implicit update by reference" was considered
loosely-coupled best-practice for a RL architecture.</p>
<p>Regards,<br>
-Peter</p></div>pdemlingtag:robotlegs.tenderapp.com,2009-10-18:Comment/170428892012-07-03T18:05:07Z2012-07-03T18:05:07ZArrayCollection filterFunction behavior: persisting Commands?<div><p>So I may have answered my own questions (but I'd be interested
to hear if you have different design opinions):</p>
<p>I located the complex filterFunction (that needs multiple
injected Models) in a separate FilterFunctionService, injected
<em>that</em> Service into my data-retrieval Service, and then
called its setFilterFunction(myArrayCollectyion) method. So it now
persists in a RL-expected way (in a Service). It is somewhat
unusual (I think?) to inject a Service into a Service; but it
seemed sensible for this purpose, and also has the advantage of
being reusable by other data-retrieval Services in the app.</p>
<p>As to getting a M's ArrayCollection to update in a V, I have the
VM listen for a "model initialized" event, and do a one-time
setting of V.dataSource = M.dataSource. Updates then automatically
happen whenever I call M.dataSource.refresh(), and I can optionally
have the VM listen for a "model refreshed" event if I need to
invoke any additional view-specific refreshing.</p>
<p>Thanks again for the assistance! Again, really loving working
with the framework (and hoping it helps us extend the viability of
Flash/Flex in the enterprise against the tidal wave of HTML5).</p>
<p>Regards,<br>
-Peter</p></div>pdemling