如果节点尚未渲染,如何从 Ext TreePanel 中删除该节点

发布于 2024-10-15 04:17:14 字数 1640 浏览 1 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只有影子陪我不离不弃 2024-10-22 04:17:14

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

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

沐歌 2024-10-22 04:17:14

我终于弄清楚了,实际上 Ext-JS 支持的 Condor 已经帮我弄清楚了。

问题是,默认情况下,当调用 TreeLoader#reload 时,TreeLoader 会清除其子级(如果 clearOnLoad 选项为 true(默认),则由 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:这是一个解决方案,而不是您建议的解决方法,但我真的很感谢你的帮助。

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:

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

@Pumbaa: This is a solution, rather than a workaround as you suggested, but I'm really thankful for your help.

魔法少女 2024-10-22 04:17:14

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

干杯,

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文