Reputation: 92274
I've found that I can't delete nodes that haven't been rendered yet. The following code shows what I mean. I ran it from the Chrome's (and Firebug's) command line while on http://dev.sencha.com/deploy/dev/exa...dow/hello.html (since that page has ext preloaded)
I typed each statement separately to make sure there were no issues with asynchronous operations (even though the tree data is in memory)
Ext.getBody.update('');
// Tree with preloaded nodes in memory
var tree = new Ext.tree.TreePanel({
renderTo: Ext.getBody(),
width: 300,
height: 500,
rootVisible: false,
loader: new Ext.tree.TreeLoader({preloadChildren:true}),
root: new Ext.tree.AsyncTreeNode({
expandend: true,
children: [
{text: 'Folder 1', id: 'folder1', leaf: false, children: [
{text: 'File 1', id: 'file1', leaf: true},
{text: 'File 2', id: 'file2', leaf: true}
]}
]
})
});
// Try to delete 'File 1', notice that the folder has never been expanded
tree.getRootNode().childNodes[0].childNodes[0].remove(true);
// Expand the node and see that 'File 1' is still there
tree.getRootNode().childNodes[0].expand();
// Delete the first child 1 again, it works now that it's been rendered
tree.getRootNode().childNodes[0].childNodes[0].remove(true);
Any suggestions on what to do?
ANSWER
var nodeToRemove = tree.getRootNode().childNodes[0].childNodes[0];
if (!nodeToRemove.rendered) {
var children = node.parentNode.attributes.children;
Ext.each(children, function(child, index){
if (child.id == nodeToRemove.id) {
chilren.splice(index, 1);
return false;
}
}) ;
} else {
nodeToRemove.remove(true);
}
Upvotes: 2
Views: 12444
Reputation: 92274
I finally figured it out, actually Condor from Ext-JS support figured it out for me.
The problem was that by default, a TreeLoader clears its children when TreeLoader#reload is called (it's called by AsyncTreeNode#expand(), if the clearOnLoad option is true (default).
(TreeLoader) load : function(node, callback, scope){
if(this.clearOnLoad){
while(node.firstChild){
node.removeChild(node.firstChild);
}
}
if(this.doPreload(node)){ // preloaded json children
this.runCallback(callback, scope || node, [node]);
}
So creating my tree loader with clearOnLoad: false
fixes my problem. Except when I remove all the child nodes. To fix that I needed the following patch:
Ext.tree.TreeLoader.prototype.doPreload =
Ext.tree.TreeLoader.prototype.doPreload.createSequence(
function(node){
if (node.attributes.children) {
node.attributes.children = [];
}
}
);
Here's a link to the ext-js thread:
@Pumbaa: This is a solution, rather than a workaround as you suggested, but I'm really thankful for your help.
Upvotes: 1
Reputation: 152956
Ext.tree.TreePanel is the one component I hate most (followed by FormPanel).
Here is what happens: The TreeLoader preloads the root node's child nodes from its original config object, and so does a call to AsyncTreeNode.expand, which will basically reset the tree.
So, you're gonna have to remove the node from your rootNode's config like this before expanding:
tree.getRootNode().attributes.children[0].children.shift();
Edit: Actually, this is more intuitive:
tree.getRootNode().childNodes[0].attributes.children.shift();
(does the same thing, since root.childNodes[0].attributes === root.attributes.children[0]
)
Upvotes: 3
Reputation: 2168
Until the treenode is expanded, the items are not yet initialized as ExtJS components. Until that time they are just sitting in the array of child items (xtyped standard javascript objects) look at TreeNode.childNodes in the API docs. Try removing them from that array and then expanding the item. That should do the trick
Cheers, Rob
Upvotes: -1