Sun 20 Jul 2008
Implementing a custom Tree “DataDescriptor” without using XML.
Posted by Mike under flex tips[3] Comments
Getting a tree to represent data in XML is fairly straight forward, and most examples use this as the default. However, what happens when you have an object tree and want to be able to represent that as the descriptor you built but also easily allow drag-drop operations (especially in cases where you need the parent object reference)?
It turns out writing a new DataDescriptor class is not necessary (as I learned the hard way), but it was necessary to figure out what they are trying to do with ancestors and child objects. While there is no defined interface for it, the data descriptor tries to figure out if the current object is parented by looking for a property called children.
So if you implement your object class with this property as an ICollectionView (it will convert to a ListCollectionView -so you might as well go the extra step to do it yourself), you’re all set.
October 30th, 2008 at 4:05 am
Hey,
currently playing with same thing. I have now children property which is ICollectionView, but I don’t know how to write MXML for such list.
throws compile error: In initializer for ‘children’: multiple initializer values for target type mx.collections.ICollectionView.
Do you know, what is the problem?
Or do you have some working example
Thank you
October 30th, 2008 at 9:03 pm
What was I was referring to here is when you have a collection of concrete objects that usually represent a model of data in some fashion that gets used in your application. Since XML has a children property already defined, it isn’t immediately obvious this is what the DataDescriptor is trying to look for.
The suggestion I made was to add a children property to each of your objects that have a sub-collection to them, and the reason why I suggested the ICollectionView interface is as a general rule any List-based component will convert a number of types to this type so you might as well do it yourself in the fashion you want.
I think the problem you might be facing is either you’re trying to assign the children property to either the list itself or the object you’re using already has the children property reference (hence the compiler says in layman’s terms: hey I already have this defined at least twice and both are telling me it’s the same type).
Typically for concrete objects these will generally be written in standard AS, but for mxml it can be done just as easily. Below is a psuedo-code example about cars.
If your root object is Ford, they make the Explorer, Focus, Taurus, etc. And each of these models has a submodel type like MX, STX, XLT, etc. They also have multiple colors.
So your Ford.mxml object:
<Script>
public function get children():ICollectionView {
return new ArrayCollection(['Explorer','Taurus','Focus']);
}
</Script>
</mx:Object>
Now if each of your Cars was a class, they’d have a children property of the sub-model type. If you also have other manufacturers you could use a collection of them (or just the 1) as the dataProvider property to a Tree-based control.
The best thing about this really comes to play is when you enable drag-drop to other components. In the DragEvent, the object reference is preserved, so you immediately have access to all the data that’s needed without having to build a complicated translation table of an xml-based object to an actual concrete object.
Hope this helps.
April 6th, 2009 at 6:40 pm
Hi Mike,
I’ve got what I think is a simpler problem, but I’m having some real difficulty finding a solution. I have a tree with the moveEnabled turned on, but I can’t figure out how to reexport the data from the modified tree control into XML. The user can move things around all day long, but I can’t figure out what’s changing underneath (not the dataProvider, clearly, nor the original XML…if it’s something in the dataDescriptor, I can’t figure out how to access it).
I’ve been Googling for hours, with no luck. Thanks.