views:

3685

answers:

8

How would I go about keeping the state of a tree control? I'd like to keep the state of the tree when it's data provider gets updated, instead of it collapsing.

A: 

I don't think there is a way to do this automatically (although i've never had to use the tree control). I would think your best bet would be to extend the tree control and handle the recording of state yourself.

For instance I would possibly override the data property so that you could run a state checking function before you set a new data object on the component. Looking at the help there are methods

isItemOpen(item:Object):Boolean,

and

expandItem(item:Object, open:Boolean, animate:Boolean = false, dispatchEvent:Boolean = false, cause:Event = null):void

You need to recursively run through each node and check if it's open and storing the state for that node. Then when it has redrawn with the new data provider, recursively run through the new nodes and check to see if any of them were previously open, and if they were, expand them.

James Hay
+2  A: 

How about something like this :

    var openItems:Object = tree.openItems;
    tree.dataProvider = myNewDataProvider;
    tree.openItems = openItems;
    tree.validateNow();

I'm not sure how well this will work if the new dataProvider is radically different from the old one, but it works when you're lazy loading tree nodes.

inferis
+1 sounds like a good call to me
James Hay
sounds great to me too, can't get the bastard to work though.When you say it should work if the dataProvider is radically different what does that mean exactly? the updated provider I'm using will have new or deleted nodes
Ronn
Actually, I've just tested it with some code that adds and removes nodes and it seems to work fine for me (there's presumably some code in the tree which checks whether the openItems exist in the tree and discards any that don't). In what way is it not working?
inferis
Well, using your snippet above my dataProvider updates, but returns the tree to a closed state. In debug mode I check the openItems and it does grab and reset them but the tree remains closed.
Ronn
At this stage you might have to post some code. Are you actually updating the dataProvider rather than creating an entirely new one each time?
inferis
No I am not modifying the existing dp, I'm creating a new one and assigning it exactly like you've stated above
Ronn
That would be your problem then. openItems contains references to specific instances and if those don't exist in your new version of the dataProvider it won't be able to open them. The code I've given works only if myNewDataProvider is the updated dataProvider, not an entirely new collection.
inferis
+1  A: 

This is actually fairly easy to do. You just have to make sure that the Component is bound to its dataProvider, rather than just referencing it. So, in mxml, that's curly brace syntax for assigning the dataProvider. Also, the DP has to be [Bindable].

If you do this, any time you update (add nodes, remove, rename, whatever) your data provider, it will be automagically updated in your control. No manual invalidating or updating required.

If you need an actual code example, let me know.

jason
And, state is retained, obviously, because you are not replacing the dataProvider, just altering.
jason
A: 

Hi Jason

I am exactly now experiencing the problem with updating the tree and keeping the state of it. Your explanation seems to solve that problem, could you post the code example here?

Thanks

A: 

You need to implement the IUID interface on your data objects that represent your nodes. The UID is a unique identifier that is usually just built off the data in the object, but sometimes it is more accurate to override this and make it some GUID that is persistent between data provider refreshes. So the above will work when using a new dataprovider if the UIDs match.

Hope that made sense.

Michelle
A: 

The easy method to keep you tree nodes expanded or collapsed even after changing the dataprovider (which is generally an ArrayCollection) is to add a property uid in the objects stored in your arraycollection.

for more such articles please visit Mithilasoft

Manish jha
A: 

Inferis's answer involving storing the openItems, and then setting them again after the data provider is updated, combined with implementing the IUID interface on the objects in the dataprovider array collection worked for me.

More info on IUID : http://livedocs.adobe.com/flex/3/html/help.html?content=about_dataproviders_8.html

mattbilson
A: 

Hi all,

For a Project with BlazeDS I had to work with updating and reloading Tree component data without breaking the User Experience (all nodes closed when data reloaded). Instead of keeping tabs on “which node was opened before?” and “what was the scroll-position?” I found a way to inject the new state of the Tree component data into the existing data provider.

See article here if you are interested. BlazeDS and Smooth Data Injection – Reloading the Tree View Data Provider without breaking the User Experience – http://bit.ly/92h7on

Hope this is of help as well.

Peter Kaptein