Updated the LookupColumn control to search for items via a hash array. The old code would loop through the source for each item witch would make the computation do R*N checks not a has array is created so that only R check's are needed. This makes a big difference is there area are large number rows or lookup items.
I highly recommend updating to this code to make renders run faster.
Here is another useful Flex component. This is a DataGridColumn that can be used to do simple lookups from another source when the DataGrid is rendered. You can use it to full data from a second source without having to first merge the data of write custom label functions.
Here is a simple example:
private const myGroups:ArrayCollection = new ArrayCollection(
[{groupid: 1, name: "Admin"},
{groupid: 2, name: "User"},
{groupid: 3, name: "Guest"}]);
<mx:DataGrid dataProvider="{}">
<mx:columns>
<mx:DataGridColumn headerText="User Name" dataField="username"/>
<LookupColumn headerText="Group" dataField="groupid" labelField="name" source="{myGroups}"/>
</mx:columns>
</mx:DataGrid>
LookupColumn.as
package hines
{
import flash.events.Event;
import mx.collections.ArrayCollection;
import mx.controls.dataGridClasses.DataGridColumn;
[Exclude(name="dataTipField", kind="property")]
/**
* This class is a custom DataGridColumn taht will look up each item in another array and fill in a field from the found item in its place.
*
* Example:
* private const myGroups:ArrayCollection = new ArrayCollection(
* [{groupid: 1, name: "Admin"},
* {groupid: 2, name: "User"},
* {groupid: 3, name: "Guest"}]);
*
* <hines:LookupColumn headerText="Group" dataField="groupid" labelField="groupname" source="{myGroups}"/>
*
* This will cause and rows with a groupid of 1 to render as "Admin" and so on.
*
* This will also work with a xml source and the lookupField can be used if the field names differ.
*
* <hines:LookupColumn headerText="Users Group" dataField="usersgroupid" lookupField="groupid" labelField="groupname" source="{myGroups}"/>
*
* @author jpyne
*/
public class LookupColumn extends DataGridColumn
{
public function LookupColumn(columnName:String=null)
{
super(columnName);
// Set up the internal lableFunction.
labelFunction = LookupColumn.doLookup;
}
//----------------------------------
// labelField
//----------------------------------
private var _labelField:String;
/**
* Field to display in the destination record. If this is not set it will default to "label".
*/
[Inspectable(category="General", defaultValue="")]
[Bindable("labelFieldChanged")]
public function get labelField():String
{
return _labelField ? _labelField : "label";
}
/**
* @private
*/
public function set labelField(value:String):void
{
_labelField = value;
dispatchEvent(new Event("labelFieldChanged"));
}
//----------------------------------
// lookupField
//----------------------------------
private var _lookupField:String;
/**
* Field to search for in the source ArrayCollection. If unset then datafield will be used.
*/
[Inspectable(category="General", defaultValue="")]
[Bindable("lookupFieldChanged")]
public function get lookupField():String
{
return _lookupField ? _lookupField : dataField;
}
/**
* @private
*/
public function set lookupField(value:String):void
{
_lookupField = value;
if(source)
prepSource();
dispatchEvent(new Event("lookupFieldChanged"));
}
//----------------------------------
// source
//----------------------------------
private var _source:ArrayCollection;
/**
* Field to display in the destination record. If this is not set it will default to "label".
*/
[Inspectable(category="General", defaultValue="")]
[Bindable("sourceChanged")]
public function get source():ArrayCollection
{
return _source;
}
/**
* @private
*/
public function set source(value:ArrayCollection):void
{
_source = value;
if(lookupField)
prepSource();
dispatchEvent(new Event("sourceChanged"));
}
//----------------------------------
// hashSource
//----------------------------------
private var _hashSource:Object;
public function get hashSource():Object
{
return _hashSource;
}
private function prepSource():void
{
_hashSource = new Object();
for each (var item:Object in source)
{
_hashSource[item[lookupField]] = item;
}
}
/**
* Override the dataTipFiled and change it to the dataField as that will be hidden.
*/
override public function get dataTipField():String
{
return dataField;
}
/**
* Look for a item in a source and display its labelField. This is an internal method and will be called for each item in teh DataGrid.
*
* @param row
* @param control
* @return
*/
static private function doLookup(row:Object, control:LookupColumn):String
{
if(control.hashSource && control.hashSource[row[control.dataField]])
return control.hashSource[row[control.dataField]][control.labelField];
// If no match was found, just return the original value.
return row[control.dataField];
}
}
}
No comments:
Post a Comment