开发者

Flex applying the sort/filter on an arraycollection without dispatching event

开发者 https://www.devze.com 2023-03-25 04:30 出处:网络
I have a object that is extended from arraycollection. This object has to access and manipulate the arraycollections source object. When this happens, the local sorted/filter copy of data goes out of

I have a object that is extended from arraycollection. This object has to access and manipulate the arraycollections source object. When this happens, the local sorted/filter copy of data goes out of sync with the source data. To line things up correctly, the sort/filter needs to be re-applied.

To do this normally, you would call refresh() on the arraycollection, but this also broadcasts a refresh event. What I want is to update the sort/filter without dispatching an event.

Having looked into the ArrayCollection class, I can see it is extended from ListCollectionView. The refresh function

public function refresh():Boolean
{
    return internalRefresh(true);
}

is in ListCollectionView and it calls this function

private function internalRefresh(dispatch:Boolean):Boolean
{
    if (sort || filterFunction != null)
    {
        try
        {
            populateLocalIndex();
        }
        catch(pending:ItemPendingError)
        {
            pending.addResponder(new ItemResponder(
                function(data:Object, token:Object = null):void
                {
                    internalRefresh(dispatch);
                },
                function(info:Object, token:Object = null):void
                {
                    //no-op
                }));
            return false;
        }

        if (filterFunction != null)
        {
            var tmp:Array = [];
            var开发者_开发技巧 len:int = localIndex.length;
            for (var i:int = 0; i < len; i++)
            {
                var item:Object = localIndex[i];
                if (filterFunction(item))
                {
                    tmp.push(item);
                }
            }
            localIndex = tmp;
        }
        if (sort)
        {
            sort.sort(localIndex);
            dispatch = true;
        }
    }
    else if (localIndex)
    {
        localIndex = null;
    }

    revision++;
    pendingUpdates = null;
    if (dispatch)
    {
        var refreshEvent:CollectionEvent =
            new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
        refreshEvent.kind = CollectionEventKind.REFRESH;
        dispatchEvent(refreshEvent);
    }
    return true;
}

annoyingly, that function is private and so is unavailable to and class that extends ListCollectionView. Also, a lot of what is in the internalRefresh function is private too.

Does anyone know of a way to call internalRefresh from a class that extends ArrayCollection? Or a way of stopping the refresh event from being dispatched when refresh is called?


My (read:hack) solution to this:

addEventListener(CollectionEventKind.REFRESH, handlerHack, true);

The true adds this listener onCapture, before anyone else gets to act on the event.

Before you call the collection.refresh() to update sort/filter, set a boolean flag to true.

discardRefreshEvent = true;
myCol.refresh();

In the listener...

private function handlerHack(evt:CollectionEvent):void
{
    if (discardRefreshEvent)
        {
            evt.stopImmediatePropagation();
            discardRefreshEvent = false;
        }
}

Disclaimer: Haven't done this exact use before (have implemented similar functionality with other events), also only guessing on Event types/names.


maybe you could extend ArrayCollection, listen to the refresh event and call stopImmediatePropagation() on it when it is fired ? I would start with this...

Good luck :-)

0

精彩评论

暂无评论...
验证码 换一张
取 消