tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/22-item-renderers-injection-and-event-handlingRobotlegs: Discussion 2018-10-18T16:35:07Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-13T20:51:58Z2009-12-13T20:52:00Z Item Renderers - Injection and event handling <div><p>In my admittedly cursory look through the examples, searches on
google<br>
and the knowledge base, I'm coming up short on examples on how
to<br>
attach eventlisteners to an item renderer from the mediator.
Any<br>
thoughts?</p></div>Danieltag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-13T21:38:57Z2009-12-13T21:38:57Z Item Renderers - Injection and event handling <div><p>If it's a custom item renderer, you could dispatch custom
bubbling events. The mediator would then simply register listeners
directly with the view component.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-13T22:12:05Z2009-12-13T22:12:05Z Item Renderers - Injection and event handling <div><p>So you don't want to listen for events on item renderers...
ever. Renderers should push events up through the list/grid that
holds them. Custom events with the data as a payload.</p>
<p><a href=
"http://www.adobe.com/devnet/flex/articles/itemrenderers_pt3.html">http://www.adobe.com/devnet/flex/articles/itemrenderers_pt3.html</a></p>
<p>Item renderers are wacky. They recycle and are in a constant
state of flux. You will reduce coupling and generally have better
days if you treat them as totally contained and never try to listen
or act on them directly from the outside.</p>
<p>That said, you could simply bubble events up. I think this
approach is poor. Hate bubbled events, especially in item
renderers. Explicit ftw...</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-13T23:25:42Z2009-12-13T23:25:42Z Item Renderers - Injection and event handling <div><p>I'm having a similar issue where I want to be able to inject a
ResourceManager so i can use localisation on strings in my item
renderers.</p>
<p>So perhaps should just pretend to be not using Robotlegs in item
renderers and use something like the built in Singleton
ResourceManager.getInstance() business?</p>
<p>I think the problem would be resolved if I could map a mediator
to an item renderer, but that doesn't work either. Hmm</p></div>Tim Oxleytag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-13T23:29:58Z2009-12-13T23:29:58Z Item Renderers - Injection and event handling <div><p>I think you are on the correct path with leveraging Flex's tools
for getting the job done. If you wanted to build a cleaner way to
accomplish this, then it would probably require ditching
ResourceManager in favor of a system you developed. I'd just deal
with the hand you are dealt and let Flex be Flex in these
situations.</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T00:46:46Z2009-12-15T00:36:33Z Item Renderers - Injection and event handling <div><p>Ahhhh, anyway, I just found a way around the problem and got the
injection working perfectly: discovered the <a href=
"http://api.robotlegs.org/org/robotlegs/core/IViewMap.html">mapPackage/mapType
functions</a> (wasn't in docs at time of writing). This will allow
injection to occur within your views, skins & item renderers
without having to manually do injections (which was a pain to do
for skins).</p>
<p>The only real issue I was having was getting Flex to inject
through all my view components. In fact I've been stressing over
this for the past week (manually injecting into all my skin classes
and whatnot) and am very relieved to have found such a simple
solution. Thanks guys.</p></div>Tim Oxleytag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T13:54:21Z2009-12-14T13:54:25Z Item Renderers - Injection and event handling <div><p>Injection into Item Renderers</p>
<p>Though I didn't really address it in my question, I did put it
in the subject line. Since it looks like someone else posted a note
about it, I will post my solution as well...</p>
<p>Injecting the resourceManager into an item renderer:</p>
<p>Summary: I've registered an IFactory with Robotlegs for the
Injections.<br>
Howto:<br>
Implement mx.core.IFactory and return your item of choice</p>
<pre>
<code>public class DnsItemRendererFactory implements IFactory {
//the property we want to inject into our item renderer
[Inject]
public var resourceManager:IResourceManager;
//This method is called by the list to create a new instance of the renderer.
//We tell it what kind to make, and inject dependencies. This all happens
//before the item is rendered
public function newInstance():*{
var renderer:DnsItemRenderer = new DnsItemRenderer();
renderer.resourceManager = resourceManager;
return renderer;
}
}</code>
</pre>
<p>In your view/mxml add the following injectable var. The name
attribute on the inject tag will help us to map this injection in
the context.</p>
<pre>
<code>[Inject(name="dnsItemRendererFactory")]
[Bindable]
public var itemRendererFactory:IFactory</code>
</pre>
<p>Also in your view/mxml reference the factory in your list as the
itemRenderer. Remember, if you just provide a class name here, flex
just creates its own class factory. We are just providing the class
factory directly:<br></p>
<pre>
<code><mx:List
dataProvider="{model.records}"
itemRenderer="{itemRendererFactory}" /></code>
</pre>
<p>Finally, in your context:</p>
<pre>
<code>//map our resourceManager dependency
injector.mapValue(IResourceManager, ResourceManager.getInstance());
//map our factory
injector.mapSingletonOf(IFactory, DnsItemRendererFactory, "dnsItemRendererFactory");</code>
</pre></div>Danieltag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T14:59:42Z2009-12-14T14:59:42Z Item Renderers - Injection and event handling <div><p>So would making a mediator for each itemRenderer a bad idea?</p>
<p>That is currently what I'm doing.</p></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T15:15:16Z2009-12-14T15:26:42Z Item Renderers - Injection and event handling <div><p>Item renderers should be completely encapsulated, reacting to
changes in their data property and dispatching events through their
list/owner that interested components can react to.</p>
<blockquote>
<p>One thing many people try to do is access an itemRenderer from
outside of the list. For example, you might want to make the cell
in the fourth column of the fifth row in a DataGrid turn green
because you've just received new data from the server. Getting that
itemRenderer instance and modifying it externally would be a huge
breech of the Flex framework and component model.</p>
</blockquote>
<p>I am in agreement with this statement. Accessing itemRenderers
directly wreaks.</p>
<p><a href=
"http://www.adobe.com/devnet/flex/articles/itemrenderers_pt1.html">http://www.adobe.com/devnet/flex/articles/itemrenderers_pt1.html</a></p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T15:30:48Z2009-12-14T15:30:50Z Item Renderers - Injection and event handling <div><p>@Joel - It appears that your comment was referencing Levi's
question about using mediators for the item renderers. Is this the
case?</p></div>Danieltag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T15:30:53Z2009-12-14T15:31:38Z Item Renderers - Injection and event handling <div><p>I agree that accessing them directly is dangerous, but if you
mediate them with the understanding that each mediator will be 1
row in the list, you can get away with accessing it directly within
the mediator can't you? You'd only get 1 mediator for each instance
of the itemRenderer and the framework would handle the wiring.</p>
<p>It's no different (conceptually) than having all that logic
between script tags on your view, is it not?</p></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T15:37:39Z2009-12-14T15:37:42Z Item Renderers - Injection and event handling <div><p>Ha! My example was flawed, forgot that mxml components already
have a reference to resourceManager in them :-)</p>
<p>It was a contrived example anyway. You could use this method to
inject other properties as needed.</p></div>Danieltag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-14T15:54:58Z2009-12-14T15:54:58Z Item Renderers - Injection and event handling <div><p>@levi It is a slippery slope that shatters the encapsulation of
item renderers. They are probably the doggiest aspect of the entire
Flex 3 framework (4 makes some great improvements here). You can
get away with practically anything, whether it is a good idea or
not. I'd never mediate item renderers and have always gone down the
pitching events up the chain route with great success.</p>
<p>@daniel yes, I was addressing Levi, but I would recommend
against injecting into item renderers generally as well. They serve
a purpose in Flex, to display (render) a single piece of data.</p>
<p>Obviously your mileage may vary.<br></p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-15T00:28:00Z2009-12-15T00:36:55Z Item Renderers - Injection and event handling <div><p>@Daniel I am using a custom resource manager implementation so
the the one provided by flex in the display classes doesn't help so
much. I hadn't thought about or looked at the factories for item
renderers before, and I guess this is what they are there for.
Thanks for putting me onto that, though this
mapPackage("com.***.views") style thing seems to just work.</p>
<p>@joel I totally understand with your sentiment regarding item
renderers just responding to the model. In my design, I'm allowing
for strings on my model to be localized on the view tier as I don't
feel this has any relevance to my model's functioning, so without
some kind of injection (automatic or not) how else am I to access
my global resource manager from the item renderer? or any other
view-specific module?</p>
<p>Now I'm thinking the alternative would be creating another layer
of abstraction between the raw model and the view (the
"view-model"?) which makes the necessary transformations ready for
the view, so all the <em>actual</em> view does is simply display
the provided data on the screen. The data comes from the
"view-model" as opposed to the model directly. Also allows for more
controlled information hiding on the raw model. That smells better
to me, what do you think?</p></div>Tim Oxleytag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-15T01:10:49Z2009-12-15T01:10:49Z Item Renderers - Injection and event handling <div><p>View-Model (aka Presentation Model) sounds like an excellent
approach.<br>
Though, the Ent artcles I linked to describe creating a custom
list/<br>
grid. You could mediate this and provide it with the dependency
and<br>
access/supply the renderers the resource manager from there.</p>
<p>this.resourceManager = this.list.resourceManager</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-15T02:25:25Z2009-12-15T02:25:25Z Item Renderers - Injection and event handling <div><p>Yes presentation model is exactly what I had in mind. Thanks
Joel. <a href=
"http://martinfowler.com/eaaDev/PresentationModel.html">http://martinfowler.com/eaaDev/PresentationModel.html</a></p></div>Tim Oxleytag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-15T03:07:26Z2009-12-15T03:07:26Z Item Renderers - Injection and event handling <div><p>Ah good, you found the Fowler article. I woulda linked it but
was on my phone ;)</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/7188172009-12-29T18:52:46Z2010-01-02T13:01:55Z Item Renderers - Injection and event handling <div><p>So far in my Flex projects i've only used Joel's approach of
dispatching a bubbling custom Event with the data from the item
renderer. ( i also once accessed methods directly on a singleton
controller class from the item renderer but i think that goes into
very-bad-practices idea).<br>
The Presentation Model idea is interesting though.</p></div>Andrei TT