Maintaining state on Tree Component while updating remote data

I suppose I’m not the only one who’s had problems with maintaining the state of a flex tree component upon updating the data. Recently I encountered the problem again and decided to crack this nut once and for all. As it turned out it was a lot easier than I had anticipated.

The Scenario
In this particular case I had a tree component displaying a hierarchical view of the pages of a web site. Upon making some certain changes, like dragging and dropping pages to reorder them I felt the need to change the order server-side and reload the data, rather than changing the order inside the dataProvider. I just like it that way better.

The Problem
So before I reloaded the data I saved the tree’s open items in a variable called openTreeItems and when I received the new data I tried to reset it by using tree.openItems = openTreeItems.
Nothing happened.

The Research
So I started doing some research and quickly discovered that to make this work the component uses the uid property and on updating the data for the dataProvider Flex reassigns new uid’s to the items in the collection. So, in short, Flex doesn’t recognize the items as the same items after the reload, because of the new uid values.

I encountered this article in the Flex 3 Help pages and started experimenting with creating custom classes that implemented the IUID interface and soon discovered that this was way to complicated for the (actually) quite simple problem I had. The pages in my database had unique ID’s! Why the h*ll couldn’t I use these values as the uid values instead of the built-in values?

The Solution
I suddenly had an idea: what if I simply add the uid property to my data serverside by using the id value I already had? This could be done in many ways but I chose to alter my SQL query like so:
“SELECT pages.id, pages.id uid, … FROM pages…”
. This way the value would be passed on into Flex the same way as all the other values.

And, voilà, it worked!
After this tiny alteration of my SQL query Flex recognized my items as the ones saved in the openTreeItems variable and when using tree.invalidateList() before the update and tree.validateNow() after the update there isn’t even a flicker upon updating the data. Sweetness!

Hope this helps anyone that has had the same problem.

3 thoughts on “Maintaining state on Tree Component while updating remote data

  1. Great i stumpled on this issue, indeed the other bypasses are alot more complicated, better to store the uids, do you happen to have some sample code ??
    would be deeply apreciated… and do you send raw xml or array collections, and how do you optain levels??
    i worked on something that had 3 static depth levels, but would like a real recursive solution, thanks again…
    Peter

  2. I have no sample code at the moment, but a side note is that this method only works with array collections and not with XML. My guess at the reason being that using an XML-file the UID-property it searches for would actually behave as “@uid” in an XML node.

    My trick to using array collections is a custom made PHP class that while transmitted through AMFPHP behaves as a native array collection, instead of an array.

    When I create the array tree in PHP, before passing it to Flex, I convert each array node to ArrayCollection using this class:

    class ArrayCollection {
    	var $_explicitType = "flex.messaging.io.ArrayCollection";
    	var $source = array();
    
    	function ArrayCollection( $array )
    	{
    		if( !isset( $array ) )
    		{
    			$array = array();
    		}
    		$this->source = $array;
    	}
    }
    

    Usage would thus be:
    $node = new ArrayCollection( $myarray );

    Hope this helps.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>