I've been meaning to blog quickly about this topic for a while. But a post from Mike over at Smart Pitbull prompted me to go ahead and do it.

Mike was having an issue with having two Flex DataGrids both bound to the same ArrayCollection. When he did something that sorted one grid, both grids would be sorted. This wasn't what he wanted, so he looked at a couple of solutions.

His first idea was to have the server convert his query into an Array, and use that to create two separate ArrayCollections based on the array. This works, but it required adding the server-side logic to do this translation.

On the advice of some readers, he dropped that solution and instead went with client-side code that loops over the result and adds each item to two separate ArrayCollections.

Actually, I think Mike's first solution was the better of the two. The second option creates two completely different ArrayCollections, which means no changes to one will be reflected in the other. One can add, remove, and modify elements in one collection and the other will remain completely unaffected. In most cases this is going to be a bad thing. Even if there are two separate grids, you probably don't want to have to manually synchronize the underlying data. Which is exactly what would have to happen here. If someone adds a User to one of the collections, the other collection (and grid) will not change. In general, you want to have a single data collection so that changes to it are immediately reflected in any views that are bound to it.

The solution that I would offer is to use two ListCollectionViews to act as the binding targets for the DataGrids. Among the many (MANY) benefits of working with my friend Joe Rinehart was that he clued me into this option very early in my Flex learning curve.

So in Mike's case, the solution is to wrap the collection returned from the server in two ListCollectionViews, one of each grid, like so:

modelData = e.result as ArrayCollection
gridData = new ListCollectionView( modelData );
advancedGridData = new ListCollectionView( modelData );

With this approach, you can sort the grids independently and not affect the other. This is because the the DataGrid (and indeed anything that sorts a collection) will apply a Sort or filterFunction directly on the bound collection. That is why you'll see both grids sort together if they are both bound to the same collection, and why the sorting is independent if each grid is bound to a different ListCollectionView. At the same time, since the underlying collection is shared by both of the ListCollectionViews, you don't need to worry about synchronizing the two collections when has elements added, removed, or changed.

I've created a simple example to show this in action. View source is enabled if you want to see what's going on. Hopefully this makes sense, and shows why using a ListCollectionView wrapper around your underlying data is a very useful option when you need to expose that data in different views.

Comments Comments (6) | del.ico.us del.icio.us | Digg It! Digg It! | Linking Blogs Linking Blogs | 12193 Views

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)

  • # Posted By Paul | 3/18/09 3:30 PM

    This is a really nice solution. That's the power of blogging not only did you show Mike the solution to him problem but now I know aswell. Thanks.

  • # Posted By Gareth Arch | 3/18/09 7:47 PM

    Dang! Now I'll have to go back and refactor my code that I just wrote :) Perfect timing though. I *think* this will work for my current problem. I had an arraycollection in a datagrid, but "the business" wanted to filter those results showing the values of certain columns and a count of the number of times that result was shown. e.g. A location list that has all cities that are in the arraycollection and a count next to each one showing the total occurrences of that location in the arraycollection, so perhaps:
    Tampa, FL (5)
    Clearwater, FL (2)
    I currently have 2 arraycollections, the original and one that I can manipulate to get those different values, but I may be able to use your method, and get updates to the data on the fly without any listeners for "collectionChange". Nice! Thanks.

  • # Posted By Ben Yee | 3/19/09 6:31 PM

    Great tip thanks for sharing

  • # Posted By Shishank(India) | 11/22/10 2:56 AM

    Hey Dang!
    One big problem i have in my application.
    When i try to sort the datagrid on a column which has similar data, it still sorts the column in an arbitrary way, which i dont want,coz ideally it should not sort as all the values are same.Please help.

  • # Posted By Brian Kotek | 11/22/10 9:37 AM

    Write a custom Sort for the column(s): http://help.adobe.com/en_US/flex/using/WS2db454920...

  • # Posted By Brian Kotek | 11/22/10 9:38 AM

    Or, simply disable sorting for the column.