Keep in mind that swapping/concating Arrays doesn't copy data around as the collections only store references to objects...
On 8/1/08, whatabrain <[EMAIL PROTECTED]> wrote: > > Replacing the dataProvider might not be more efficient if a lot of > rows are added all at once, to a table that already has a lot of > rows. Then you end up copying much more data around. Though > admittedly, that would be a very rare occurrence in the project I'm > working on. > > The other problem is saving off expand/collapsed state and multiple- > select state, but that wouldn't be too hard. And then there's the > inevitable flicker. > > In any case, I found a simple solution that solves the problem. I > call expandItem() twice before calling enableAutoUpdate(). This > collapses and then expands the node, allowing a fast update to hidden > items and emptying the ListCollectionView event queue. Now, adding > 1000 items takes just one second. Plus, select state is preserved. > > Do you see any long-term problems with this approach? > > Thanks again for all your help! > > > --- In flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com>, "Alex > Harui" <[EMAIL PROTECTED]> wrote: > > > > 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 <flexcoders%40yahoogroups.com> > [mailto:flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com>] On > > Behalf Of whatabrain > > Sent: Friday, August 01, 2008 1:29 PM > > To: flexcoders@yahoogroups.com <flexcoders%40yahoogroups.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 <flexcoders%40yahoogroups.com><mailto: > flexcoders% <flexcoders%25> > 40yahoogroups.com> > > , "whatabrain" <junk1@> 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 <flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com <flexcoders%2540yahoogroups.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 <flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com <flexcoders%2540yahoogroups.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 <flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com <flexcoders%2540yahoogroups.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<flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com <flexcoders%2540yahoogroups.com>> > > > > > [mailto:flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com <flexcoders%2540yahoogroups.com>> ] > *On > > > > > > > Behalf Of *whatabrain > > > > > > > *Sent:* Thursday, July 31, 2008 3:23 PM > > > > > > > *To:* flexcoders@yahoogroups.com<flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com <flexcoders%2540yahoogroups.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. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >