Back in the days when Commodore were able to advertise 64K of memory as being synonymous with the large memory of an elephant
, stack overflow errors were common. With limited memory, only a small amount could be spared for the stack, and a series of function calls could easily fill it up.
These days, when computers have 5-6 orders of magnitude more memory, the concept of a stack overflow has been relegated to an in-joke name for an excellent developer Q & A site. I was therefore more than a little surprised when a Flex app produced the following stack trace:
<span style="color: #993366;">Error: Error #1023: Stack overflow occurred.
Scrolling down through the stack trace, everything that came after what I’ve copied above was just many references to the one method. I’d written a recursive method who’s test for the end of the recurse would always fail, so it had gone into an “infinite loop”. It just goes to show, no matter how much memory you have, a run-away recursive method will always run out of stack space. Stack overflow errors still exist, they are simply hidden away from all but sloopy recursion junkies… 🙂
If you have ever tried to display filtered data in a Flex component, you’ll likely be aware that you can use an XMLListCollection
object as the data source and that you can apply a filter function to that collection. The component only then displays the filtered data. However if you have tried this with a Tree component, you’ll have discovered that it doesn’t work. The filter is only applied to the top-level node(s) in the collection. The filter isn’t recursively applied to child nodes.
There is a an open bug related to this problem in the Flex Bug and Issue Management System. It is currently targeted to be fixed for Flex 3.4.0. In the meantime though, there is a simple work-around that I’ll describe here.
When rendering its nodes, a Tree object relies on a helper class that implements one of the ITreeDataDescriptor or ITreeDataDescriptor2 interfaces. By default it is an instance of DefaultDataDescriptor, but one is free to supply the tree with a different implementation. By overriding the tree’s data descriptor with one that supports filtering, the tree’s content can be easily filtered. The simple Flex SWF below demonstrates this point. Try selecting/ unselecting the checkboxes on the right and you’ll see that the tree’s content changes accordingly.
http://www.davidarno.org/wp-content/uploads/2009/03/filterabletree.swf, 450, 350
The key to how it works is that the tree calls the data descriptor’s getChildren() method for each node. The filter function can therefore be called at this point and we only return to the tree the set of children that we want displayed.
My implementation of the ITreeDataDescriptor is far from complete. I have only implemented those methods needed to demonstrate the point, though it implements the required functionality just fine. The DefaultDataDescriptor is more complex, as it implements all the methods, plus it uses some clever caching mechanisms. I may implement a full replacement class at some stage that will support drag and drop for example, but for now that is left as an exercise for any reader who needs such functionality.
You can download the full FlexBuilder project source code for the above SWF here.