Lazy Loading Tree example file posted

english mobile

A lot of people on the flexcoders yahoo list have asked about creating a tree that uses a custom DataDescriptor to allow lazy loading of the data. In other words, it gets the first level of data when the application loads, but does not call for the children of the branches until each node is open. I had a bit of down time this week, so I thought I'd put one together.

This example actually has two ways to lazy load. The first is the obvious one using a custom DataDescriptor that is designed to work with any class that is written to the LazyLoading Interface. The major things it does are


  1. Tell the tree that the branch "intends" to have children even when no children have been loaded.

  2. When a branch is loaded, it tells the LazyLoading to load its children.


This could be slicker, in that I could have extended the Tree to listen for the load to finish, but I chose not to do that.

The second way that the lazy loading can be done is to not use the DefaultDataDescriptor at all, but to instead let the instances of Classification load themselves. This code is in place in the hasChildren setter--you'd just need to uncomment it.

This example is unusual in that it not only uses RemoteObject to retrieve the data, it contains the php files and instructions to recreate the mySQL database, so even if you're mainly looking for an AMFPHP example, you might find it helpful.

The bad part about about this example is that I can't post the working example due to reasons I've already blogged about, so you'll just have to look at this pretty picture and take it on faith that if you follow the instructions below that you've got a really good shot at producing a working lazy loading tree application. (As of 1-14-09, you can click this image to see the working example with View Source enabled. See note at end of post.)


  • First, install AMFPHP to your server. I'm going to assume in these steps that you did it to the "flashservices" directory referred to in the installation instructions. I'd suggest that you test the service browser at this point to identify any showstoppers before you get too far.
  • Next, download the flex project zip file and import it to your Flex builder workspace.
  • Download the rtf translation of the mySQL database table export. This is simply the ".sql" file created from the table export with the extension changed to rtf and some formatting added to make your life easier.
  • Download the zip with the php services files. Extract them and place them in the flashservices/services directory. If you didn't install AMFPHP to the flashservices directory, adjust accordingly.
  • Create a new mySQL database called 'RemoteServiceTest'.
  • Open the classification.rtf file you downloaded earlier.
  • Log into phpAdmin or whatever you're using to administer your mySQL databases. Select your new database, and go to the "SQL" panel. In the classification.rtf file, select all of the text that is bold and red and copy it. Paste it into the sql window and run the query. Repeat with the blue, bold text (but only once with each block of text). I got an error with this one about a duplicate key, but it all seemed to come in just fine.
  • Adjust your project properties so that your debug and release builds are exported to the right location relative to the flashservices directory. Alternatively, adjust the setChannels() function in the ClassificationGetter to point to where your service actually is.
  • Enjoy!

Updated 1-14-09:

Reader David Becarra in Mexico donated a subdomain running PHP 5 so that I could show a running example of this. I don't think that he's accepting new hosting subscribers at the moment, but his website is http://www.misitioweb.net/. BIG THANK YOU, David!!

8 comments:

Steve Howard said...

You've been tagged 7 Random Things

http://stevehoward.blogspot.com/2009/01/7-random-things.html

:-) I know. You hate me now :-)

Vax said...

Hi Amy
Ive been searching the internet for weeks trying to figure out how to run a function in a 3rd party flash file. Would you happen to know if its possible? Basically I want to call a function in another flash file, one that I know the exact location of, but I do not know how to call it. Does the third party flash file have to make the function available to the outside?

I have seen programs be able to 'run script' into a flash file, and I have tried calling the function (in the third party flash file) and it works. However I have no idea how the program is accomplishing this..

Im sorry for adding a comment to this post but I could not find another way to contact you :)

krikri said...

Hello Amy,
I try to adapt your tree with zend_amf , but i didn't arrive.
Can you help me please.
Thank's.
krikri

Goltia said...

Hello Amy,

Thanks for this example. I adapt it and it works prety well.
Just a thing, in the loadChildren method in Classification, you dispatch the CHILDREN_LOADED event even when the object is already loading children.
To my mind, you mustn't do anything when the class is loading children.
I've got some bug with your implementation of loadChildren so I juste change this :

public function loadChildren():void {
if(!_isLoadingChildren){
if (_children.length==0 && _hasChildren) {
_isLoadingChildren=true;
ClassificationGetter.execute(id, onChildrenLoaded, onChildrenLoadFailed);
} else {
dispatchEvent(new Event(CHILDREN_LOADED));
}
}
else{
//Nothing to do. The event will be dispatched when children will be loaded
}
}

I just wonder if is there a particular reason to your implementation.

Fabi said...

If you wantan example with webservice let's go my blog : http://fabi-net.blogspot.fr/search/label/flex ...

Amy B said...

Note that my subdomain got nuked. My apologies for everyone who tried to see this code while it was down. It has been restored.

Unknown said...

Hi Amy,

Thanks for your code example. It is working well, although I can't seem to trace out the hadChildren() property, and maybe I am just missing the bigger picture.

I have a hierarchy that is simple:

- root company
- child company
- user
- user
(repeat child)

If I load the root node, it has child companies, but I haven't yet loaded the children users of a node until it gets clicked (lazy). Your Classification object's hasChildren indicates it's set "if there are any other Classifications that have a parentID that is equal to the id of this Classification". However, I won't know until I hit the database onClick to find out.

How is this supposed to work in this scenario?

Thanks in advance!

Amy B said...

It's been a long time since I've looked at this code, but I believe that the query that gets the items does a count on child items with that parent ID. The database and PHP are available in the download.