So, I've been trying to figure out how to get a non-hierarchical data
set to work with the Flex 2 Tree control.
My data is a simple array of Objects. Each object has a member called
PARENT_ID; this is either the string ID of its parent, or ''
signifying that it should be on the uppermost level. (Each Object
also has an ID member, being a string that is its own ID.)
I started out by making a ITreeDataDescriptor. That works fine.
After defining all of the functions, the nodes are drawn correctly
depending on whether or not they have children. Also, when a node is
expanded it draws the indented children correctly.
However, this is where my functionality grinds to a halt.
In addition to the nodes being drawn underneath their expanded parent,
they are also drawn in the root list (ie, depth = 1). I'm guessing
it's because the dataprovider isn't hierarchical, so the component
doesn't know to not draw the nodes whose PARENT_ID != ''.
Furthermore, when I expand a parent and mouse over one of its
children, the Tree does not highlight the children I'm over, but
instead it highlight the duplicate that has been drawn further down
the list.
I thought that the data descriptor was going to handle this, but it
must not; that or I'm missing something in the descriptor.
I've been poking around in the updateDisplayList of tree, and it looks
like it's going to be very messy to try and get things to not draw.
Any ideas?
----------
Data:
[Bindable]
protected var flatData:Array = [
{ID:'1',
NAME:'Node1',
PARENT_ID:''},
{ID:'1-1',
NAME:'Child 1-1',
PARENT_ID:'1'},
{ID:'1-2',
NAME:'Child 1-2',
PARENT_ID:'1'},
{ID:'1-2-1',
NAME:'Child 1-2-1',
PARENT_ID:'1-2'},
{ID:'1-2-2',
NAME:'Child 1-2-2',
PARENT_ID:'1-2'},
{ID:'1-3',
NAME:'Child 1-3',
PARENT_ID:'1'},
{ID:'2',
NAME:'Node2',
PARENT_ID:''},
{ID:'2-1',
NAME:'Child 2-1',
PARENT_ID:'2'},
{ID:'2-2',
NAME:'Child 2-2',
PARENT_ID:'2'},
{ID:'2-2-1',
NAME:'Child 2-2-1',
PARENT_ID:'2-2'},
{ID:'2-2-2',
NAME:'Child 2-2-2',
PARENT_ID:'2-2'},
{ID:'2-3',
NAME:'Child 2-3',
PARENT_ID:'2'}];
ITreeDataDescriptor:
package descriptors
{
import mx.collections.ICollectionView;
import mx.controls.treeClasses.ITreeDataDescriptor;
import mx.collections.IViewCursor;
import mx.collections.ArrayCollection;
import mx.collections.Sort;
import mx.collections.SortField;
public class FlatTreeDataDescriptor implements ITreeDataDescriptor
{
public function getData(node:Object, model:Object=null):Object {
try {
return node;
} catch ( error:Error ) {
}
return null;
}
public function hasChildren(node:Object,
model:Object=null):Boolean {
if ( model && model is ArrayCollection ) {
var sort:Sort = new Sort();
sort.fields = [new SortField("PARENT_ID",
true)];
ArrayCollection(model).sort = sort;
ArrayCollection(model).refresh();
var cursor:IViewCursor;
cursor = ArrayCollection(model).createCursor();
}
if ( cursor.findAny( {PARENT_ID:node.ID} ) ) {
return true;
}
return false;
}
public function addChildAt(parent:Object, newChild:Object,
index:int, model:Object=null):Boolean
{
return false;
}
public function isBranch(node:Object,
model:Object=null):Boolean {
if ( model && model is ArrayCollection ) {
var sort:Sort = new Sort();
sort.fields = [new SortField("PARENT_ID",
true)];
ArrayCollection(model).sort = sort;
ArrayCollection(model).refresh();
var cursor:IViewCursor;
cursor = ArrayCollection(model).createCursor();
}
if ( cursor.findAny( {PARENT_ID:node.ID} ) ) {
return true;
}
return false;
}
public function removeChildAt(parent:Object, child:Object,
index:int, model:Object=null):Boolean
{
return false;
}
public function getChildren(node:Object,
model:Object=null):ICollectionView {
var children:Array = new Array();
for ( var i:int = 0; i < ArrayCollection(model).length;
i++ ) {
if (
ArrayCollection(model).getItemAt(i).PARENT_ID == node.ID )
children.push(
ArrayCollection(model).getItemAt(i) );
}
if ( children.length > 0 )
return new ArrayCollection(children);
return null;
}
}
}
-------
Side note: I know that ArrayCollection(model) isn't the best
practice, but I just wanted to get it working.
Any ideas or suggestions are appreciated.
Thanks,
Nathan