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 :-)
精彩评论