How to delete a node from an Ext TreePanel if the node hasn't been rendered
Solution 1
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.
Solution 2
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]
)
Ruan Mendes
Client side/ middle tier web developer. Have programmed in C, C++, C#, Groovy, Java, ActionScript, Lingo, JavaScript, PHP, TypeScript. Basic My language of choice is TypeScript, on the browser or Deno. Technologies I've worked with substantially: HTML, CSS, DOM, AJAX, Angular, React, jQuery, Google Closure Templates, Sencha touch, Ext-JS ASP, PHP, JSP, Struts, Velocity, Node.js, Kohana Windows, Unix, OpenVMS, Solaris Ant, make, maven XML-RPC, RESTful services JSUnit, JUnit, PhpUnit, Karma, Jasmine, js-test-driver, NUnit, YUI tests Selenium, Cucumber, Cypress Grails ASP.NET
Updated on June 04, 2022Comments
-
Ruan Mendes almost 2 years
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); }
-
Ruan Mendes over 13 yearsHi Rob: By using a treeloader with preloadChildren set to true, all the nodes in the children array are instantiated when the treepanel is rendered (though the corresponding TreeNodeUI is not rendered until it's expanded). What do you mean by remove them from that array? That is what my code is doing. You probably meant remove from the attributes.children array, but that doesn't work: attributes.children is irrelevant after the TreeNode objects have been created from the config and put into the childNodes array.
-
Ruan Mendes over 13 yearsI'm trying it now... you are saying that my code should work but the tree loader is not smart enough to detect that it's preloaded the children for the node and it recreates them from the attributes.children array?
-
Ruan Mendes over 13 yearsIt works, thanks! I am going to look for the actual bug in their code.
-
Ansel Halliburton over 13 yearsRight. Actually, it's not the loader's job to remember which nodes have been preloaded. The root node flags itself loaded. Still,
Folder 1
is not flagged loaded, so once you callexpand()
, the loader jumps in again.