Something to remember when working with inline components in Flex

Last night I ran into an issue I just couldn't understand with some Flex development I was doing. Let me show the code that wasn't working:

<mx:DataGridColumn dataField="filename_thumbnail" headerText="Thumbnail" width="250"> <mx:itemRenderer> <mx:Component> <mx:Image height="50" width="50" source="{(data.thumbnail_filename!=null)?baseurl+'/images/spotlight/'+data.thumbnail_filename:baseurl+'/images/spotlight/'+data.filename}" /> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn>

This code creates an inline component to render an image in a data grid. I use some simple logic to see if the thumbnail column has a value. If it does, I want to show that image. If not, I want to show the value in the image column.

My original code had a hard coded path in it, which of course didn't work when the code was sent to production. (Duh.) So I switched to using a variable baseurl. This was a valid variable (I could Alert it inside my MXML file), but I kept getting an unknown variable error when I tried to compile it.

Luckily I was able to find help on the cfflex IRC channel. Toby Tremayne found this from the docs:

The <mx:Component> tag defines a new scope within an MXML file, where the local scope of the item renderer or item editor is defined by the MXML code block delimited by the <mx:Component> and </mx:Component> tags. To access elements outside of the local scope of the item renderer or item editor, you prefix the element name with the outerDocument keyword.

http://livedocs.adobe.com/flex/201/langref/mxml/component.html

Turns out - this inline component acted like a whole other MXML file. A bit like how a ColdFusion custom tag would act if we could define one inline. What I don't quite get is why I can access data ok. I'm assuming Flex passes it in automatically since it recognizes I'm in a datagrid.

As the docs say, it is easy enough to fix. I simply add the outerDocument keyword like so:

<mx:DataGridColumn dataField="filename_thumbnail" headerText="Thumbnail" width="250"> <mx:itemRenderer> <mx:Component> <mx:Image height="50" width="50" source="{(data.thumbnail_filename!=null)?outerDocument.baseurl+'/images/spotlight/'+data.thumbnail_filename:outerDocument.baseurl+'/images/spotlight/'+data.filename}" /> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn>

Archived Comments

Comment 1 by Ken Dunnington posted on 4/10/2007 at 5:37 PM

You're right, Flex populates the 'data' property when creating the inline renderer with the current row data. It does something similar for list controls with the 'listData' property. I believe all control components have these two properties (though they're empty by default.) I was playing around with inline renderers recently and came up against the same problem accessing variables outside the mx:Component tag.

Comment 2 by Raymond Camden posted on 4/10/2007 at 5:50 PM

Ok, so I'm not alone in being caught by this. :)

Comment 3 by Arul posted on 4/10/2007 at 8:01 PM

Thanks for the info. It will save lot of time and effort :)

Comment 4 by Rick Root posted on 4/11/2007 at 6:41 AM

I think when I came across this I figured out pretty quickly that it was a scoping issue.

I ended up solving it by using mx.core.application.Application.varname (or something like that)

Later, I discovered that "parentDocument" is much easier to type, as is parentApplication.

I've never seen "outerDocument" before... like all good programming languages, there are a billion ways to do things.

Comment 5 by Elliott Sprehn posted on 4/11/2007 at 1:04 PM

"What I don't quite get is why I can access data ok. I'm assuming Flex passes it in automatically since it recognizes I'm in a datagrid."

If you're really interested then set the compiler setting to save the generated AS3 code and you can see what your MXML is actually doing.

Its a good way to understand the magic that is MXML and what mxmlc is really generating for you.

Comment 6 by Raymond Camden posted on 4/11/2007 at 4:07 PM

How is that done?

Comment 7 by hua posted on 4/11/2007 at 7:56 PM

to save the generated as3 code:
http://www.cornilliac.com/m...

Comment 8 by Raymond Camden posted on 4/11/2007 at 8:02 PM

Nice. Thanks!