Replacing the dataProvider isn't the best option for my particular 
application, since requests to add rows will come in at random 
intervals, and I don't want to lose selection state and such.

So I've written the code such that, if two add requests happen within 
300ms of each other, I call disableAutoUpdate. If, after that, 500ms 
go by with no add requests, I call enableAutoUpdate().

But now, adding 1000 rows takes just as long as before. With the tree 
collapsed (or with a regular DataGrid), it takes 1 second. With the 
tree opened, it takes 8, with or without auto-update.

Any idea why this might be? I can switch to replacing the 
dataProvider and only running this optimization when the app first 
loads, but I'd rather not.

More information: The dataProvider is a subclass of ArrayCollection, 
which contains objects with a "children" member, which is another 
ArrayCollection.


private var m_lastAdd:Number = 0;
private var m_autoUpdateEnabled:Boolean = true;

// This is called 1000 times
private function AddItem(name:String):void
{
var now:Number = (new Date()).getTime();
if (m_autoUpdateEnabled && (now - m_lastAdd < 300))
{
gridData.disableAutoUpdate();
m_autoUpdateEnabled = false;
setTimeout(flushAddQueue, 500);
}
m_lastAdd = now;
[Then call the add function, which puts items into the 0th group]
}

private function flushAddQueue():void
{
if (!m_autoUpdateEnabled && ((new Date()).getTime() - m_lastAdd < 
300))
{
gridData.enableAutoUpdate();
m_autoUpdateEnabled = true;
}
else
setTimeout(flushAddQueue, 500);
}



Thanks for all your help so far!


--- In flexcoders@yahoogroups.com, "Daniel Gold" <[EMAIL PROTECTED]> 
wrote:
>
> I've seen a lot of posts with performance related to using Bindable
> Collections like that. One of the dangerous of having such a useful 
easy API
> for updating controls...
> 
> Just to expand on what Alex is suggesting, suppose your service 
call returns
> to a function called updateData, and your control is bound to a 
_data
> ArrayCollection
> 
> public function updateData(newData:IList):void
> {
>      var newData:Array =[];
>      for each(var data:Object in IList)
>      {
>           _newData.push(data);
>      }
>      _data.source = newData;
>      _data.refresh();
> }
> 
> That's an extremely basic code example, and actually unnecessary to 
loop
> like that in most cases, but basic principle is get your data 
structured in
> an Array or similar structure, add new items, remove old 
unnecessary items,
> whatever you need to do, concat or replace the source Array of your
> ArrayCollection, and then call refresh which will dispatch a
> COLLECTION_CHANGE event which will trigger any controls using it as 
a
> dataProvider to update.
> 
> On Thu, Jul 31, 2008 at 6:47 PM, Alex Harui <[EMAIL PROTECTED]> wrote:
> 
> >    There is enable/disableAutoUpdate, but adding rows one at a 
time is
> > inefficient.  Just concat the two arrays and replace the 
dataprovider
> >
> >
> >  ------------------------------
> >
> > *From:* flexcoders@yahoogroups.com 
[mailto:[EMAIL PROTECTED] *On
> > Behalf Of *whatabrain
> > *Sent:* Thursday, July 31, 2008 3:23 PM
> > *To:* flexcoders@yahoogroups.com
> > *Subject:* [flexcoders] How to temporarily stop a dataProvider 
from
> > updating UI
> >
> >
> >
> > I've found that adding a lot of rows (1000+) to an 
AdvancedDataGrid can
> > be quite slow, if the rows happen to be visible (in an open node 
of the
> > tree). I don't know why this is the case, especially since it's 
not the
> > case in a regular DataGrid, but I'd like to work around it.
> >
> > So how can I tell the AdvancedDataGrid to temporarily ignore 
updates to
> > the dataProvider? Once the large number of rows have been added, 
I'll
> > turn the automatic updating back on, for the slow trickle of 
updates
> > that come after that.
> >
> >  
> >
>


Reply via email to