ListCollectionView: Different perspectives on data
In a recent project one of the challenges was to display data to the user in a variety of different ways with little overhead. In the .net world we used DataViews to create multiple perspectives on the same DataSet. This included sorting and filtering the data without needing multiple copies of the data in memory. When I first started snooping around in Flex I figured there had to be a way to get the same functionality, and soon I found the ListCollectionView.
As a side note, I'll soon start putting running samples up here with source code, just been too lazy to ftp them up to my server. Anyway let's dig in to the code. First we have a handy dandy xml data file:
<?xml version="1.0" encoding="UTF-8"?>Then we have to load the xml into an arraycollection, however several of the boolean properties will need to be reworked during the data load. Here's what that looks like:
<items>
<item name="Item 1" quantity="2" price="20.00" size="small"
rebate="yes" discontinued="yes" />
<item name="Item 2" quantity="4" price="10.00" size="medium"
rebate="no" discontinued="yes" />
<item name="Item 3" quantity="4" price="25.00" size="small"
rebate="no" discontinued="no"/>
<item name="Item 4" quantity="1" price="5.00" size="extra-large"
rebate="no" discontinued="yes" />
<item name="Item 5" quantity="3" price="30.00" size="small"
rebate="yes" discontinued="yes" />
<item name="Item 6" quantity="4" price="17.00" size="medium"
rebate="no" discontinued="yes" />
<item name="Item 7" quantity="1" price="12.00" size="extra-large"
rebate="yes" discontinued="no"/>
<item name="Item 8" quantity="4" price="22.00" size="extra-large"
rebate="yes" discontinued="yes" />
</items>
<mx:HTTPService id="itemConn" url="items.xml"So now we have an ArrayCollection of itemsIS, let's add a DataGrid and set the dataprovider to this collection:
useProxy="false" result="resultItemHandler(event)"/>
...
private function resultItemHandler(event:ResultEvent):void {
var source:ArrayCollection =
itemConn.lastResult.items.item as ArrayCollection;
var cursor:IViewCursor = source.createCursor();
var result:ArrayCollection = new ArrayCollection();
while (!cursor.afterLast){
var currentObj:Object = cursor.current;
var cv:String = currentObj["rebate"];
cv = cv.toUpperCase();
var newValue:Boolean = false;
if (cv == "YES" ){
newValue = true;}
currentObj["rebate"] = newValue;
cv = currentObj["discontinued"];
cv = cv.toUpperCase();
newValue = false;
if (cv == "YES" ){
newValue = true;}
currentObj["discontinued"] = newValue;
result.addItem(currentObj);
cursor.moveNext();
}
itemsIS = result;
}
<mx:DataGrid id="itemDG" dataProvider="{itemsIS}"The next step requires a filtered view that will only show discontinued items, so we're going to add a LinkButton
editable="false" width="100%" height="100%"/>
<mx:LinkButton label="Discontinued" click="handleDisc()"/>and then add the following code to our script section:
[Bindable]In this function we are creating a ListCollectionView that wraps our itemsIS collection. Then we create and set the filter function inline, and call a refresh(). Then we set the dataProvider of the datagrid to our ListCollectionView. You could add any number of "views" on the data in this way, and then let the user switch quickly between them.
private var itemsDiscontinued:ListCollectionView;
public function handleDisc():void{
itemsDiscontinued = new ListCollectionView(itemsIS);
itemsDiscontinued.filterFunction =
function ( item:Object):Boolean {return item.discontinued};
itemsDiscontinued.refresh();
itemDG.dataProvider = itemsDiscontinued;}
Here's the code in action
1 comment:
It may be a long time on since the original post, but thanks for such a great example.
Paul
Post a Comment