Ext JS 4:过滤TreeStore

inc*_*nez 6 tree extjs store extjs4

我最初发布这个在煎茶论坛,在这里却没有得到(比我自己的答案,我会很快发布其他)任何回应,所以我要在这里重新发布一下,看看是否我得到了帮助.

我一直在讨论如何在4.0.7中过滤TreeStore.我尝试过以下方法:

该模型

Ext.define('model', {
  extend: 'Ext.data.Model',
  fields: [
    {name: 'text', type: 'string'},
    {name: 'leaf', type: 'bool'},
    {name: 'expanded', type: 'bool'},
    {name: 'id', type: 'string'}
  ],
  hasMany: {model: 'model', name: 'children'}
});
Run Code Online (Sandbox Code Playgroud)

商店

Ext.define('myStore', {
  extend: 'Ext.data.TreeStore',
  model: 'model',
  storeId: 'treestore',
  root: {
    text: 'root',
    children: [{
      text: 'leaf1',
      id: 'leaf1',
      children: [{
        text: 'child1',
        id: 'child1',
        leaf: true
      },{
        text: 'child2',
        id: 'child2',
        leaf: true
      }]
    },{
      text: 'leaf2',
      id: 'leaf2',
      leaf: true
    }]
  },
  proxy: {
    type: 'memory',
    reader: {
      type: 'json'
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

那个树

var myTree = Ext.create('Ext.tree.Panel', {
  id: 'myTree',
  selType: 'cellmodel',
  selModel: Ext.create('Ext.selection.CellModel', {mode: 'MULTI'}),
  rootVisible: false,
  store: Ext.create('myStore'),
  width: 300
});
Run Code Online (Sandbox Code Playgroud)

过滤器

var filter = Ext.create('Ext.util.Filter', {
  filterFn: function(item) {
    return item.data.text == 'leaf1';
  }
});
Run Code Online (Sandbox Code Playgroud)

所以我认为我的问题是......我不知道如何使用这个过滤器,因为TreeStore实际上没有继承任何类型的过滤器函数,如普通商店.我试过了:

myTree.store.filters.add(filter);
myTree.store.filters.filter(filter);  // This seems to work
// I can get into the filterFn when debugging, but I think item is the "this" of my filter object.
Run Code Online (Sandbox Code Playgroud)

通常情况下,如果我有一个网格并且我创建了一个像上面那样的过滤器,我可以这样做myTree.store.filter(filter),它会抓住我返回的每一行的项目/过滤器......但我在想,因为TreeStore不会继承过滤功能那是没有传入的.

如果有人能够清楚地说明我做错了什么,或者对如何设置过滤功能/思考过程有任何见解,请继续.我很感激任何帮助.

Aci*_*ier 6

感谢抓住另一个,我修复了答案,包括我下面包含的更动态的树库过滤器覆盖来回答你的问题.

它在4.1b2中工作正常,我知道4.07和4.1之间的树库有一些变化,但我认为4.07仍然有我在这里使用的树对象.

这是覆盖:

Ext.override(Ext.data.TreeStore, {

    hasFilter: false,

    filter: function(filters, value) {

        if (Ext.isString(filters)) {
            filters = {
                property: filters,
                value: value
            };
        }

        var me = this,
            decoded = me.decodeFilters(filters),
            i = 0,
            length = decoded.length;

        for (; i < length; i++) {
            me.filters.replace(decoded[i]);
        }

        Ext.Array.each(me.filters.items, function(filter) {
            Ext.Object.each(me.tree.nodeHash, function(key, node) {
                if (filter.filterFn) {
                    if (!filter.filterFn(node)) node.remove();
                } else {
                    if (node.data[filter.property] != filter.value) node.remove();
                }
            });
        });
        me.hasFilter = true;

        console.log(me);
    },

    clearFilter: function() {
        var me = this;
        me.filters.clear();
        me.hasFilter = false;
        me.load();
    },

    isFiltered: function() {
        return this.hasFilter;
    }

});
Run Code Online (Sandbox Code Playgroud)

它使用store.tree.nodeHash对象来迭代所有节点而不是第一个子节点.它将接受过滤器作为函数或属性/值对.我认为clearFilter方法可以解决,以防止另一个ajax调用.