Thursday, March 11, 2010

Flex/ActionScript - Item Renderers Issue (Items not being rendered as required)

Hi People!

It's been a very very long time since I posted something! So here is some Flex/ActionScript stuff. (Some C# stuff is coming soon ;))!

This post is about correcting the issue encountered while using item renderers in DataGrids. I am not a UI guy and this post mainly concentrates on how to solve and not any fancy stuff. Coming to the point, when using datagrids in Flex, the default "rowCount" attribute would be roughly 7/8. Assume you are setting the "rowCount" attribute to "10". Now when Flex renders the data grid, only 10 itemRenderer instances are created as the user will initially be able to view only 10 rows. And if you are using itemRenderers you are most likely to render them using multiple properties from the dataProvider. Consider the following data grid column:

<mx:DataGridColumn headerText="Attachments" dataField="Id and HasAttachment and ServerID" itemRenderer="renderer.AttachmentColRenderer" />

Here the item renderer "AttachmentColRenderer" would be using the following properties from the dataProvider: Id, HasAttachment, ServerID. I got in to a problem while using item renderers. The issue was that, the first 10 items were displayed as per the requirement. But while scrolling/paging I noticed that the items rendered were not according to what they should be. For example, I had to make a link button visible if there was an attachment and vice versa. But for some items the link button appeared even though there were no corresponding downloads. Before using this solution I was using the "creationComplete" event to manipulate the controls as required.

The issue was that Flex reuses the instances of the item renderers created initially. And so, the data wouldn't be set during reuse causing this issue. To overcome this add the following in the item renderer


<mx:Script>
<![CDATA[
// Over ride the "set" method so that every instance gets appropriate data
override public function set data(value:Object):void
{
// At times you 'may' get a null
if (value != null)
{
// super.data would normally hold the data for this instance
super.data = value;

// Process the data as per requirements from this point
if (super.data.HasAttachment.toString() == "true")
{
lnkDownload.visible = true;
}
else
{
lnkDownload.visible = false;
}
}
}
]]>
</mx:Script>

Here I need to override the set data method, so that the data that corresponds this particular instance is being set. After this the items were rendered as expected. If you are a flex person, the above snippet would immediately make sense, so I guess no explanation is needed!

Happy coding!

~ Karthik

No comments: