Howdy all....
I've been searching and reading and trying just about every example I
can find to delete a tree node, but nothing seems to work. I've
looked at Peter Ent's code, but couldn't get that to work. There was
also a posting on the Adobe forums where someone was doing something
very similir to what I'm using and eventually got their to work, but
never posted how.
I'm using a modified version of the custom ITreeDataDescriptor example
that looks for "items" instead of "children". My tree is being
populated with a highly nested arraycollection.
When it execute the removeChildAt function, it's using Splice and is
supposed to remove the 1st item after the index parameter, but nothing
happens. The tree dataprovider remains the same. If someone can give
me a hand and tell me what I'm doing wrong, I would be most
appreciative!
Below is the code I'm using:
public class ItemAsChildTreeRender implements ITreeDataDescriptor
//public class ItemAsChildTreeRender extends TreeItemRenderer
{
// The getChildren method requires the node to be an Object
// with a children field.
// If the field contains an ArrayCollection, it returns the field
// Otherwise, it wraps the field in an ArrayCollection.
public function getChildren(node:Object,
model:Object=null):ICollectionView
{
try
{
if (node is Object) {
if(node.item is ArrayCollection){
return node.item;
}else{
var ac:ArrayCollection=new
ArrayCollection(mx.utils.ArrayUtil.toArray(node.item)) ;
//return new ArrayCollection(node.item as Array);
return ac
}
}
}
catch (e:Error) {
trace("[Descriptor] exception checking for getChildren");
trace ("error:" + e.message);
}
return null;
}
// The isBranch method simply returns true if the node is an
// Object with a children field.
// It does not support empty branches, but does support null children
// fields.
public function isBranch(node:Object, model:Object=null):Boolean {
try {
if (node is Object) {
if (node.item != null) {
return true;
}
}
}
catch (e:Error) {
trace("[Descriptor] exception checking for isBranch");
}
return false;
}
// The hasChildren method Returns true if the node actually has children.
public function hasChildren(node:Object, model:Object=null):Boolean {
if (node == null)
return false;
var children:ICollectionView = getChildren(node, model);
try {
if (children.length > 0)
return true;
}
catch (e:Error) {
}
return false;
}
// The getData method simply returns the node as an Object.
public function getData(node:Object, model:Object=null):Object {
try {
return node;
}
catch (e:Error) {
}
return null;
}
// The addChildAt method does the following:
// If the parent parameter is null or undefined, inserts
// the child parameter as the first child of the model parameter.
// If the parent parameter is an Object and has a children field,
// adds the child parameter to it at the index parameter location.
// It does not add a child to a terminal node if it does not have
// a children field.
public function addChildAt(parent:Object, child:Object, index:int,
model:Object=null):Boolean {
var event:CollectionEvent = new
CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
event.kind = CollectionEventKind.ADD;
event.items = [child];
event.location = index;
if (!parent) {
var iterator:IViewCursor = model.createCursor();
iterator.seek(CursorBookmark.FIRST, index);
iterator.insert(child);
}
else if (parent is Object) {
if (parent.item != null) {
if(parent.item is ArrayCollection) {
parent.item.addItemAt(child, index);
if (model){
model.dispatchEvent(event);
model.itemUpdated(parent);
}
return true;
}
else {
parent.item.splice(index, 0, child);
if (model)
model.dispatchEvent(event);
return true;
}
}
}
return false;
}
// The removeChildAt method does the following:
// If the parent parameter is null or undefined, removes
// the child at the specified index in the model.
// If the parent parameter is an Object and has a children field,
// removes the child at the index parameter location in the parent.
public function removeChildAt(parent:Object, child:Object, index:int,
model:Object=null):Boolean
{
//super.removeChildAt(parent,child,index,model);
var event:CollectionEvent = new
CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
event.kind = CollectionEventKind.REMOVE;
event.items = [child];
event.location = index;
//handle top level where there is no parent
if (!parent)
{
var iterator:IViewCursor = model.createCursor();
iterator.seek(CursorBookmark.FIRST, index);
iterator.remove();
if (model)
model.dispatchEvent(event);
return true;
}
else if (parent is Object)
{
if (parent.hasOwnProperty("item") && parent.item != undefined)
{
parent.item.splice(index, 1);
if (model)
model.dispatchEvent(event);
return true;
}
}
return false;
}
}
My MXML is as follows:
<mx:Tree id="printTree" change="publicTreeChanged(event)"
dataDescriptor="{new util.ItemAsChildTreeRender()}" dropEnabled="true"
labelField="name" width="100%" height="100%"/>
<mx:Button id="deleteBtn" label="Remove Selected Node"
click="doDeleteCase(event)" x="147" y="354"/>
My Delete code is:
public function publicTreeChanged(event:Event):void {
selectedNode =
printTree.dataDescriptor.getData(Tree(event.target).selectedItem);
}
public function doDeleteCase(event:Event):void{
printTree.dataDescriptor.removeChildAt(printTree.firstVisibleItem,
selectedNode, printTree.selectedIndex);
}