【问题标题】:Expanding tree nodes before AJAX has ended in ExtJS在 ExtJS 中 AJAX 结束之前扩展树节点
【发布时间】:2026-01-18 09:55:01
【问题描述】:

我的树面板上有一个搜索栏。当我写一些东西并按下回车键时,一个 Ajax 请求会触发并返回将树展开到请求的文件夹点所需的文件夹 ID。在 ajax.request 的成功配置中,我使用循环通过 getNodeById 调用每个节点的扩展函数。然而,在第一次扩展后,ExtJS 会触发来自代理的 ajax 请求以获取文件夹数据(因为它尚未加载)。由于 AJAX 是异步的,因此循环比服务器响应更快,它会在节点本身加载之前尝试调用节点的 .expand() 函数并给出未定义的错误。我应该如何解决这个问题?我知道通常使用 AJAX,您必须在处理请求后对要运行的所有内容使用回调函数,但我不确定在这种情况下如何执行此操作...

Ext.define('treeStore', 
{
    extend : 'Ext.data.TreeStore',
    alias: 'widget.treeStore',
    autoLoad : false,
    model : 'treeModel',
    root :  {
        id: 0,
        name : 'Root', 
        expanded : true,
        loaded: true
    },
    proxy :  {
        type : 'ajax', 
        url : 'MyServlet', 
        reader :  {
            type : 'json', 
            root : 'children'
        }
    },
    folderSort: true
});

Ext.define('Ext.tree.Panel',{
.
.
.
//Stuff about the tree panel etc.
dockedItems: {
        xtype: 'textfield',
        name: 'Search',
        allowBlank: true,
        enableKeys: true,
        listeners: { 
            specialkey: function (txtField, e) { 
                if (e.getKey() == e.ENTER){
                    var searchValue = txtField.getValue();
                    Ext.Ajax.request({
                        url: 'MyServlet',
                        params: {
                            caseType: 'search',
                            value: searchValue
                        },
                        success: function(response) { //ATTENTION: When calling the .expand() the AJAX hasn't finished and cannot find the node.
                            response = Ext.decode(response.responseText);
                            var panel = txtField.up();
                            response.IDs.forEach(function(entry){
                                panel.getStore().getNodeById(entry.folderId).expand(); <-problem here
                            });
                        }
                    });
                }
            }
        }
    }

【问题讨论】:

  • 我发现expand()函数本身有一个回调函数。我正在尝试找到正确的方法来利用它。有什么想法吗?

标签: javascript ajax extjs tree extjs4


【解决方案1】:

在编写我的 Ext 应用程序时,我经常发现即使事情应该按顺序触发,但有时在 AJAX 调用之后立即调用事情有时太快了。也许树节点还没有正确渲染,或者其他问题。

尝试围绕该代码封装一个延迟任务:

new Ext.util.DelayedTask(function()
{
    response = Ext.decode(response.responseText);
    var panel = txtField.up();
    response.IDs.forEach(function(entry){
        panel.getStore().getNodeById(entry.folderId).expand(); <-problem here
    });
}, this).delay(100);

不过,您必须解决这些范围问题。延迟函数之前的“this”就是你的作用域。

【讨论】:

  • 它不能解决问题。我尝试了 setTimer 方法,但这不是所需要的。 setTimer 在执行内部函数之前等待 X 时间,但程序本身不会等待。我想要的是程序停止前进,等待 AJAX 响应加载文件夹树数据然后继续。 setTimer 不会停止程序运行,它会继续运行,只是在 X 秒后触发该函数。这对我没有帮助,因为如果文件夹数据尚未加载,则无处可去。