AlBirdie
AlBirdie

Reputation: 2071

AS3/Flex apply sort to ArrayCollection only once

I've got an ArrayCollection that serves as a dataProvider for a list.

The collection stores objects of type MyObject:

public class MyObject {
    public var myMap:Dictionary;
}

myMapstores key-value pairs, the key being an integer, the values are Strings.

So far for the constraints. What I want to do now is to sort the collection based on fields of the map.

Using a the ArrayCollection's sort function with my own compareFunction does work. This is how I've implemented it:

    var key:int = 15;
    var sort:Sort = new Sort();
    sort.compareFunction = fidSort;
    myCollection.sort = sort;
    myCollection.refresh();

    private function fidSort(a:Object, b:Object, fields:Array = null):int {
        if(a.myMap[key].fieldValue == b.myMap[key].fieldValue) {
            return 0;
        } else if(a.myMap[key].fieldValue > b.myMap[key].fieldValue) {
            return 1;
        } else{
            return -1;
        }
    }

As I said, that does work for the sake of sorting. However, naturally the sort (being a property of the collection) remains on the collection unless specifically removed from it, which means that every time a value in the map of MyObject changes, it will get sorted according the comparefunction.

What I need is to apply the sort exactly once, what happens afterwards with the map values shouldn't change the collections sorting.

I've tried things like disabling autoupdate on the colleciton (naturally that won't work as the collection doesn't get any updates any more (well it does, but they are cached only)). After that I've read this post about sorting the underlying array. However, that doesn't seem to work with the map, as I do get a compile error saying that the myMap[key].fieldValue couldn't be found on MyObject.

So yes, I'm kinda lost in space here. If someone has a clue how to achieve this, very basic task really, please let me know.

Cheers!

Upvotes: 0

Views: 1774

Answers (1)

AlBirdie
AlBirdie

Reputation: 2071

Got it, and for the sakes of completeness, I'd like to answer this question myself.

As said before, using myCollection.toArray().sort(fidSort) didn't work completely. The array made in this step has indeed been sorted, the collection, however, didn't get the sort, even though refresh() has been called.

To fix this, instead of creating a new array from the collection, we need to directly use the collection's source (which is an array of course) and sort that array;

  collection.source.sort(fidSort);
  collection.refresh();

Since we are still only sorting the array and not applying the Sort to the collection itself, the collection is sorted only once, regardless of the updates to it's data.

Edit: Just for kicks, restoring the original item positions isn't possible out of the box when sorting the collection's underlying array like it can be done when applying a sort on an ArrayCollection directly and setting it to null to restore the positions. Simple solution is to cache the array item indices beforehand.

Upvotes: 2

Related Questions