Something to remember when working with inline components in Flex

This post is more than 2 years old.

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>
Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

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!