How do I stop a datagrid's first-row itemRenderer from instantiating/adding/initializing/etc twice?
- by Michael Prescott
In a Flex DataGrid's first row, the itemRenderer will initialize twice. Tracing the results reveals that the flex framework is possibly creating two instances of the first row's itemRenderer. In a more complex application, where the itemRenderer contains a data-bound ColorPicker, we're seeing an infinite loop occur because of this problem. Only the first row's itemRenderer is initialized twice. Is there a way to override flex's behavior and stop this from occurring? The following code demonstrates the problem:
Main Application:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="on_initialize(event);">
<mx:Script>
<![CDATA[
/**
* This experiment shows how the first row's itemrenderer is instantiated/added/initialized twice.
* We've never even noticed this before we found that a data-bound ColorPicker enters a infinite
* loop when it is within an itemRenderer.
*/
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
private var dg_array:Array;
private var dg_arrayCollection:ArrayCollection;
private function on_initialize(event:FlexEvent):void {
dg_array = new Array();
dg_arrayCollection = new ArrayCollection();
dg_arrayCollection.addItem("item 1");
dg_arrayCollection.addItem("item 2");
dg.dataProvider = dg_arrayCollection;
}
]]>
</mx:Script>
<mx:DataGrid id="dg" width="100%" height="100%" rowCount="5">
<mx:columns>
<mx:DataGridColumn headerText="Name" itemRenderer="SimpleItemRenderer"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
SimpleItemRenderer:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" initialize="//on_initialize(event);">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
[Bindable]
override public function set data(value:Object):void { _data = value; }
override public function get data():Object { return _data; }
private var _data:Object;
private function on_initialize_textInput(event:FlexEvent):void {
trace("initialize:event.target="+event.target+", " + _data); // runs twice, for the first item only
}
private function on_creationComplete_textInput(event:FlexEvent):void {
trace("creationComplete:event.target="+event.target+", " + _data); // runs twice, for the first item only
}
]]>
</mx:Script>
<mx:TextInput text="{data}" id="textInput" initialize="on_initialize_textInput(event);" creationComplete="on_creationComplete_textInput(event);"/>
</mx:Canvas>
Abbreviated Output:
initialize:event.target=ItemRenderers0.dg...SimpleItemRenderer12.textInput, null
initialize:event.target=ItemRenderers0.dg...SimpleItemRenderer24.textInput, null
creationComplete:event.target=ItemRenderers0.dg...SimpleItemRenderer24.textInput, item 1
initialize:event.target=ItemRenderers0.dg...SimpleItemRenderer29.textInput, null
creationComplete:event.target=ItemRenderers0.dg...SimpleItemRenderer29.textInput, item 2
creationComplete:event.target=ItemRenderers0.dg...SimpleItemRenderer12.textInput, item 1