【问题标题】:ExtJs Tree loading sequenceExtJs 树加载顺序
【发布时间】:2016-02-24 15:51:03
【问题描述】:

美好的一天。

我正在用 Ext.tree.Panel 编写一个树控件,它从外部 .json 文件加载其配置,而数据从服务器加载为 .json。

所以,我有这样的看法:

Ext.define('App.tree.TreeView', {
    extend: 'Ext.tree.Panel',
    ...
    initFilters: function(cfg) {
        /*several this.store.addFilter() based on cfg*/
    },   
    initComponent: function () {
        var me = this;
        me.cfg = getSomeCfgFromSomewhere();
        me.initFilters(me.cfg);
    }    
});

商店:

Ext.define('Site.widgets.tree.TreeStore', {
    extend: 'Ext.data.TreeStore',
    ...
    proxy: { 
        type: App.cfg.proxy, 
        reader: { type: 'json', rootProperty: 'data.children' }, 
        format: App.cfg.proxy.urlEnd, 
        url: App.cfg.treeRoot, 
        noCache: false
    }
    lazyFill: true,

    rootVisible: true,
    root: {
        full_path: '/', /*set as idProperty in model*/
        'display-name': 'root',
        expanded: true
    },
});

问题是:我的根是在商店中明确设置的,因为 expanded: true 加载了它的内容。但是只有这些内容显示在树中,没有根本身。删除过滤后,tre 加载正常。

可能原因:在ext-all-debug.js中调试Sencha代码:视图的initComponent在store开始加载数据之前被调用,因此在加载数据之前添加了过滤器,当root 还是空的,然后调用

onNodeFilter: function(root, childNodes) {
    var me = this,
        data = me.getData(),
        toAdd = [];
    if (me.getRootVisible()) {
        if (childNodes.length) {
            toAdd.push(root);
        } else {
            root.set('visible', false, me._silentOptions);
        }
    }
    ...
}

,即根被设置为不可见,因为它仍然是空的,然后才加载根的孩子。

问题是:我的过滤器初始化中是否存在初始设计错误,我该如何解决?

【问题讨论】:

    标签: javascript extjs tree


    【解决方案1】:

    考虑到问题是在商店开始加载数据之前调用了视图的initComponent,我会尝试:

    在 store 加载事件中调用 initFilters,如下所示:

    Ext.define('Site.widgets.tree.TreeStore', {
        extend: 'Ext.data.TreeStore',
        ...
        proxy: { 
            type: App.cfg.proxy, 
            reader: { type: 'json', rootProperty: 'data.children' }, 
            format: App.cfg.proxy.urlEnd, 
            url: App.cfg.treeRoot, 
            noCache: false
        }
        lazyFill: true,
    
        rootVisible: true,
        root: {
            full_path: '/', /*set as idProperty in model*/
            'display-name': 'root',
            expanded: true
        },
        listeners : {
            load : function() {
                 //Call initFilters. 
                 //initFilters should call addFilter just once, 
                 //with array of filters as first parameter, 
                 //to avoid filtering the hole tree more than once!
            }
        }
    });
    

    这种方式有问题,因为你要处理initFilters cfg参数作用域。

    【讨论】:

    • 后端返回一个由节点的full_path 成员中包含的路径定义的节点,从而动态加载树。根必须描述我要加载的子树的“上”节点,稍后我希望能够从外部更改它。我的代理实际上是这样的:proxy: { type: App.cfg.proxy, reader: { type: 'json', rootProperty: 'data.children' }, format: App.cfg.proxy.urlEnd, url: Site.cfg.url.treeRoot, noCache: false }
    • 感谢您的帮助。我自己尝试的第一件事,但它并没有改变行为。第二个可能有效,但在任何加载事件中初始化过滤器似乎是一个相当昂贵的修复,因为它们中的每一个都调用整个树的过滤,并且通常有大约 6 个过滤器。
    • 不客气! addFilter 方法接受一个过滤器数组作为第一个参数,所以你可以调用它一次!
    • 哦,好的,在我的代码中修复了过滤器初始化,谢谢。尝试以您发布的第二种方式执行此操作 - 它奏效了!尽管如此,这在每次加载时都会这样做,而我宁愿在初始化时只做一次,但我还是应该支持你的解决方案。
    【解决方案2】:

    好的,原来答案的一部分就在问题中:我可以通过在我的商店中简单地重载 onNodeFilter() 方法来解决这个问题,因为我知道我想始终显示根。如果有人可以提出更好的建议 - 请做我的客人。

    【讨论】:

    • 很好,至少您找到了解决方案! =)
    猜你喜欢
    • 2013-04-03
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多