2

我发现我无法删除尚未渲染的节点。下面的代码说明了我的意思。我在http://dev.sencha.com/deploy/dev/exa...dow/hello.html上从 Chrome(和 Firebug)的命令行运行它(因为该页面已预加载 ext)

我分别输入了每个语句以确保异步操作没有问题(即使树数据在内存中)

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);

关于做什么的任何建议?

回答

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);
}
4

3 回答 3

3

Ext.tree.TreePanel 是我最讨厌的一个组件(其次是 FormPanel)。

以下是发生的情况: TreeLoader 从其原始配置对象预加载根节点的子节点,调用AsyncTreeNode.expand 也是如此,这将基本上重置树。

因此,在扩展之前,您必须像这样从 rootNode 的配置中删除该节点:

tree.getRootNode().attributes.children[0].children.shift();

编辑:实际上,这更直观:

tree.getRootNode().childNodes[0].attributes.children.shift();

(做同样的事情,因为root.childNodes[0].attributes === root.attributes.children[0]

于 2011-01-31T23:44:08.830 回答
1

我终于想通了,实际上来自 Ext-JS 支持的 Condor 为我想通了。

问题在于,默认情况下,如果 clearOnLoad 选项为 true(默认),则 TreeLoader 在调用 TreeLoader#reload 时会清除其子项(它由 AsyncTreeNode#expand() 调用)。

 (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]);
        }

所以创建我的树加载器clearOnLoad: false解决了我的问题。除非我删除所有子节点。为了解决这个问题,我需要以下补丁:

Ext.tree.TreeLoader.prototype.doPreload = 
Ext.tree.TreeLoader.prototype.doPreload.createSequence(
  function(node){
    if (node.attributes.children)  {
      node.attributes.children = [];    
    }
  }
);

这是 ext-js 线程的链接:

http://www.sencha.com/forum/showthread.php?122681-Deleting-unrendered-nodes-from-a-tree-doesn-t-work&p=567459#post567459

@Pumbaa:这是一个解决方案,而不是您建议的解决方法,但我非常感谢您的帮助。

于 2011-02-02T18:33:34.157 回答
-1

在树节点展开之前,项目尚未初始化为 ExtJS 组件。在那之前,他们只是坐在子项数组(xtyped 标准 javascript 对象)中,查看 API 文档中的 TreeNode.childNodes。尝试从该数组中删除它们,然后扩展该项目。这应该够了吧

干杯,罗伯

于 2011-01-31T23:24:42.087 回答