I think it will be more efficient to simply reset the source, saving away the selectedIndex first and restoring it (after updating if necessary) later. It might be possible to create your own IList implementation that handles addItemsAt and sends the appropriate change event, but I'm not sure all of those code paths have been exercised.
________________________________ From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On Behalf Of whatabrain Sent: Friday, August 01, 2008 1:29 PM To: flexcoders@yahoogroups.com Subject: [flexcoders] Re: How to temporarily stop a dataProvider from updating UI Ok, I've learned a little more. When you re-enable auto updates, ListCollectionView.handlePendingUpdates() is called. This function optimizes row-update operations, combining them into a single event, but row-add operations get handled one by one. So the adds are no more efficient with auto-updates disabled than enabled. Is there any way to refresh the entire list, and prevent the update queue from being flushed? I tried calling refresh() before enableAutoUpdates(), but it actually prevents the update from happening at all. Rows only get added in the visible area -- no scrollbar is created until I collapse and expand the parent node. --- In flexcoders@yahoogroups.com <mailto:flexcoders%40yahoogroups.com> , "whatabrain" <[EMAIL PROTECTED]> wrote: > > Sorry for cluttering the group... > > I found one more detail. If, instead of disabling auto-update on the > root node, I do it on the first (and currently only) child node: > > gridData[0].children.disableAutoUpdate(); > > and don't re-enable updates, rows still get added, but only up to the > limit of the AdvancedDataGrid's current scroll area. If I then > collapse and expand the root, I see all the rows. > > If I do enable auto-update later on the child, the rows get drawn, > but it takes even longer than without this trick (14 seconds instead > of 8). > > > > --- In flexcoders@yahoogroups.com <mailto:flexcoders%40yahoogroups.com> , "whatabrain" <junk1@> wrote: > > > > Huh. I just noticed that when I comment out the line that calls > > enableAutoUpdate(), auto-update still happens. This tells me I'm > > doing something wrong. Any ideas? > > > > > > > > --- In flexcoders@yahoogroups.com <mailto:flexcoders%40yahoogroups.com> , "whatabrain" <junk1@> wrote: > > > > > > 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 <mailto:flexcoders%40yahoogroups.com> , "Daniel Gold" <danielggold@> > > > 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 <aharui@> 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:flexcoders%40yahoogroups.com> > > > [mailto:flexcoders@yahoogroups.com <mailto:flexcoders%40yahoogroups.com> ] *On > > > > > Behalf Of *whatabrain > > > > > *Sent:* Thursday, July 31, 2008 3:23 PM > > > > > *To:* flexcoders@yahoogroups.com <mailto:flexcoders%40yahoogroups.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. > > > > > > > > > > > > > > > > > > > > > > > > >