Working with the Flex consumer class and datagrids

Posted: May 20th, 2009

I was recently working on a Flex app that showed delayed stock quotes and charts. The client was using Blaze DS on the backend. It is one of the best ways to hook Flash/Flex to a data source and absolutely perfect for this project. We were using the consumer class in Flex and once the subscribe method was called, new poll results were coming in every second. The poll results were in the form of an array collection and were displayed in multiple datagrids nested inside containers behind a TabNavigator and others in an Accordion.

I pulled these controls into seperate components and used binding to get the data to “trickle” down into the controls. The Accordion had four different panes, each with a datagrid, and each had a different filter for the data. Easy, assign a filter function and call the refresh function on the accordion change event.

The problem that we ran into was that we were losing our selected item in the datagrid every time new poll results came in. What I found to be the best solution: Create a variable that holds the value of the selected index of the datagrid. Assign it when the change event is triggered. Then create a setter for the array collection and assign the selected index of the datagrid to the value of the variable that holds your selectedIndex.

Click through to see the code.

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
show="initGrid()" width="100%">
<mx:Script>

	<![CDATA[
	import mx.collections.ArrayCollection;
	import mx.events.ListEvent;	

	/*
	 * Accessor here keeps the right index selected
	 */
	[Bindable]
	public var _dataForAccordion:ArrayCollection = new ArrayCollection();

	[Bindable]
	public function set dataForAccordion(val:ArrayCollection):void
	{
		 if (dataGrid != null ) {
			this._dataForAccordion = val;
			dataGrid.selectedIndex = this.selectedItem;
		}
	}
	public function get dataForAccordion():ArrayCollection
	{
		return this._dataForAccordion;
	}

	/*
	 * Other vars
	 */
	private var selectedItem:int = 0;		

        /*
	 * This causes the first item in the datagrid to be selected
	 * when it is first displayed
	 */
	public function initGrid():void
	{
              dataGrid.selectedIndex = this.selectedItem;
	}
	/*
	 * This function commits a selection on a DataGird rollover
	 */
	private function handleRollOver(event:ListEvent):void
	{
		this.selectedItem = event.rowIndex;
		event.target.selectedIndex = event.rowIndex;
	}

	]]>

</mx:Script>
	<mx:DataGrid id="dataGrid" itemRollOver="handleRollOver(event)"
        width="468" height="210" dataProvider="{_dataForAccordion}" >
		<mx:columns>
			<mx:DataGridColumn dataField="property1"
                        width="45" headerText="property1"/>

			<mx:DataGridColumn dataField="property2"
                        width="45" headerText="property2"/>

			<mx:DataGridColumn dataField="property3"
                        width="45" headerText="property3"/>

			<mx:DataGridColumn dataField="property4"
                        width="45" headerText="property4"/>
		</mx:columns>
	</mx:DataGrid>
</mx:Canvas>

Leave a Reply