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.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
>  
>

Reply via email to