Flex применяет сортировку / фильтр к коллекции массивов без отправки события

У меня есть объект, расширенный от arraycollection. Этот объект должен иметь доступ к исходному объекту arraycollections и управлять им. Когда это происходит, локальная отсортированная / отфильтрованная копия данных не синхронизируется с исходными данными. Чтобы выровнять все правильно, необходимо повторно применить сортировку / фильтр.

Чтобы сделать это в обычном режиме, вы должны вызвать refresh () для коллекции array, но при этом также будет транслироваться событие обновления. Я хочу обновить сортировку / фильтр без отправки события.

Заглянув в класс ArrayCollection, я увидел, что он расширен от ListCollectionView. Функция обновления

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

находится в ListCollectionView и вызывает эту функцию

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;
}

досадно, что эта функция является частной и поэтому недоступна для класса, расширяющего ListCollectionView. Кроме того, многое из того, что находится в функции internalRefresh, также является частным.

Кто-нибудь знает, как вызвать internalRefresh из класса, расширяющего ArrayCollection? Или способ остановить отправку события обновления при вызове обновления?


person Zone12    schedule 03.08.2011    source источник
comment
Из любопытства, почему вы хотите, чтобы событие обновления не транслировалось?   -  person Jason Towne    schedule 03.08.2011
comment
Потому что это происходит не в то время и заставляет все, что просматривает ArrayCollection, перерисовывать / перезагружать всю свою информацию. Это также не соответствует обычному способу работы ArrayCollection. Событие обновления должно отправляться только после изменения сортировки или фильтра.   -  person Zone12    schedule 03.08.2011


Ответы (2)


Мое (читай: взломать) решение для этого:

addEventListener(CollectionEventKind.REFRESH, handlerHack, true);

Значение true добавляет этот прослушиватель onCapture до того, как кто-либо еще сможет обработать событие.

Прежде чем вызывать collection.refresh () для обновления сортировки / фильтра, установите для логического флага значение true.

discardRefreshEvent = true;
myCol.refresh();

В слушателе ...

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

Отказ от ответственности: раньше не использовали точно такое использование (реализовали аналогичные функции с другими событиями), также только предполагая типы / имена событий.

person Sam DeHaan    schedule 03.08.2011
comment
Я думаю, что так мне и нужно будет делать это, пока я не получу Adobe принять мой запрос функции. - person Zone12; 03.08.2011
comment
Учитывая этот метод, попробуйте, и он, похоже, блокирует больше функций, из-за чего он не работает должным образом. Думаю, мне придется глубже погрузиться в код. - person Zone12; 04.08.2011
comment
Что ж, если у вас возникнут более конкретные проблемы, не стесняйтесь продолжать комментировать здесь или открывать новый вопрос, и я сделаю все возможное, чтобы помочь вам. - person Sam DeHaan; 04.08.2011
comment
На самом деле, в конце концов, это заработало. StopImmediatePropagation означает, что текущий объект не получал события. Вместо этого использование StopPropagation заставило его работать правильно. - person Zone12; 08.09.2011

возможно, вы могли бы расширить ArrayCollection, прослушать событие обновления и вызвать для него stopImmediatePropagation () при его запуске? Я бы начал с этого ...

Удачи :-)

person LoremIpsum    schedule 03.08.2011