Over a million developers have joined DZone.

Data Paging in Flex 4

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

I know — you’ve heard it from me before — AMF rocks! With AMF you can load massive amounts of data into your Flex (or JavaScript) apps very quickly. This can often obviate the need for paging data. But what if you have lots, and lots, and lots of data? Well then you should use data paging. And here is how…

There is a new collection wrapper class in Flex 4 called “AsyncListView“. The UI data controls in Flex 4 know how to handle an AsyncListView as a dataProvider. The purpose of the AsyncListView is to give you a callback when the underlying list throws an ItemPendingError. The ItemPendingError indicates that an item that the list thinks it has isn’t really there yet. This allows you to then load the data and update the list. In order to throw an ItemPendingError you need to keep track of which items haven’t been loaded and then, when an item is requested that isn’t really there, throw the ItemPendingError. Here is some code from my PagedList implementation:

public function getItemAt(index:int, prefetch:int = 0):Object
{
if (fetchedItems[index] == undefined)
{
throw new ItemPendingError("itemPending");
}

return _list.getItemAt(index, prefetch);
}

In my main application I just create a PagedList, set its length (which should really be done by a remote call instead of manually), and then assign the instance of PagedList to the list property on my instance of AsyncListView. With MXML this looks like:

<local:PagedList id="items" length="100000"/>
<s:AsyncListView id="asyncListView" list="{items}"
createPendingItemFunction="handleCreatePendingItemFunction"/>

When the ItemPendingError is thrown, the handleCreatePendingItemFunction is called. Now I just figure out what page of data is needed, make sure that there isn’t already a pending request for that page, and then make the request. When the response comes back I simply update the underlying collection. Here is the code that does that:

private function handleCreatePendingItemFunction(index:int, ipe:ItemPendingError):Object
{
var page:uint = Math.floor(index / pageSize);
if (fetchedPages[page] == undefined)
{
var numItemsToFetch:uint = pageSize;
var startIndex:uint = pageSize * page;
var endIndex:uint = startIndex + pageSize - 1;
if (endIndex > items.length)
{
numItemsToFetch = items.length - startIndex;
}
var asyncToken:AsyncToken = ro.getElements(startIndex, numItemsToFetch);
asyncToken.addResponder(new AsyncResponder(function result(event:ResultEvent, token:Object = null):void {
for (var i:uint = 0; i < event.result.length; i++)
{
items.setItemAt(event.result[i], token + i);
}
}, function fault(event:FaultEvent, token:Object = null):void {
}, startIndex));
fetchedPages[page] = true;
}
return null;
}

In this example I’m using RemoteObject (AMF) but this could be anything (HTTPService, WebService, etc.) as long as there is a method on the back end that lets me set the starting location and the page size.

Here is a simple demo of data paging using the new Spark DataGrid in Flex Hero. The page size is 100 and there are 100,000 total items.


Of course another option for doing data paging more automatically is with LiveCycle Data Services. Check out a great example of Data Paging with LCDS in Tour de Flex to learn more about that.

A big thanks to Mike Labriola for helping me figure this out! Please let me know if you have any questions about this.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Published at DZone with permission of James Ward. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}