Ext JS 4:过滤 TreeStore [英] Ext JS 4: Filtering a TreeStore
问题描述
我最初在 Sencha 论坛上发布了这篇文章here 但没有得到任何回复(除了我自己的答案,我将很快发布),所以我将在这里重新发布,看看我是否能得到更多帮助.>
我一直在绞尽脑汁思考如何在 4.0.7 中过滤 TreeStore.我尝试了以下方法:
模型
Ext.define('模型', {扩展:'Ext.data.Model',字段: [{名称:'文本',类型:'字符串'},{名称:'叶',类型:'布尔'},{名称:'扩展',类型:'bool'},{名称:'id',类型:'字符串'}],hasMany:{模型:'模型',名称:'儿童'}});
商店
Ext.define('myStore', {扩展:'Ext.data.TreeStore',模型:'模型',storeId: 'treestore',根: {文字:'根',孩子们: [{文字:'叶1',id: '叶 1',孩子们: [{文字:'child1',id: 'child1',叶子:真的},{文字:'child2',id: 'child2',叶子:真的}]},{文字:'叶2',id: '叶 2',叶子:真的}]},代理人: {类型:'记忆',读者:{类型:'json'}}});
树
var myTree = Ext.create('Ext.tree.Panel', {id: 'myTree',selType: '细胞模型',selModel: Ext.create('Ext.selection.CellModel', {mode: 'MULTI'}),根可见:假,商店:Ext.create('myStore'),宽度:300});
过滤器
var filter = Ext.create('Ext.util.Filter', {filterFn:功能(项目){返回 item.data.text == 'leaf1';}});
所以我认为我的问题是...我不知道如何使用这个过滤器,因为 TreeStore 实际上没有像普通商店那样继承任何类型的过滤器功能.我试过了:
myTree.store.filters.add(filter);myTree.store.filters.filter(filter);//这似乎有效//调试的时候可以进入filterFn,但是我觉得item是我的filter对象的this".
通常,如果我有一个网格并且我创建了一个像上面一样的过滤器,我可以只做 myTree.store.filter(filter)
并且它会根据我的内容抓取每一行的项目/过滤器返回...但我在想,因为 TreeStore 没有继承过滤功能,所以没有传入.
如果有人可以澄清我做错了什么或对如何设置过滤功能/我的思考过程有任何见解,请继续.我很感激任何帮助.
感谢您发现另一个,我修复了将答案包含在我在下面回答您的问题时包含的更动态的树存储过滤器覆盖.
它在 4.1b2 中运行良好,我知道在 4.07 和 4.1 之间对 treestore 进行了一些更改,但我认为 4.07 仍然具有我在这里使用的树对象.
这是覆盖:
Ext.override(Ext.data.TreeStore, {hasFilter:假,过滤器:函数(过滤器,值){如果(Ext.isString(过滤器)){过滤器 = {属性:过滤器,价值:价值};}var me = 这个,解码 = me.decodeFilters(filters),我 = 0,长度 = 解码.长度;for (; i < 长度; i++) {me.filters.replace(解码[i]);}Ext.Array.each(me.filters.items, function(filter) {Ext.Object.each(me.tree.nodeHash, function(key, node) {如果(filter.filterFn){if (!filter.filterFn(node)) node.remove();} 别的 {if (node.data[filter.property] != filter.value) node.remove();}});});me.hasFilter = true;控制台日志(我);},清除过滤器:函数(){var me = this;me.filters.clear();me.hasFilter = false;我.加载();},isFiltered: 函数() {返回 this.hasFilter;}});
它使用 store.tree.nodeHash
对象针对过滤器迭代所有节点,而不仅仅是第一个子节点.它将接受过滤器作为函数或属性/值对.我想可以通过 clearFilter 方法来防止另一个 ajax 调用.
I originally posted this on the Sencha forums here but didn't get any responses (other than my own answer, which I will post soon), so I am going to repost it here and see if I get anymore help.
I've been racking my brain on how to filter a TreeStore in 4.0.7. I've tried the following:
The model
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'}
});
The store
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'
}
}
});
The tree
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
});
The filter
var filter = Ext.create('Ext.util.Filter', {
filterFn: function(item) {
return item.data.text == 'leaf1';
}
});
So I think my problem is... I don't know how to use this filter due to TreeStore not actually inheriting any type of filter functions like a normal store. I've tried:
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.
Normally, if I have a grid and I create a filter like above, I can just do myTree.store.filter(filter)
and it'll grab each row's item/filter on what I return... but I'm thinking because TreeStore doesn't inherit a filtering function, that's not being passed in.
If someone could provide some clarity as to what I'm doing wrong or any insight on how to set up a filter function/my thinking process, please go ahead. I'd appreciate any help.
Thanks for catching that other one, I fixed up the answer to include the more dynamic treestore filter override that I included below to answer your Q.
It is working fine in 4.1b2, I know there were some changes to the treestore between 4.07 and 4.1 but I think 4.07 still had the tree objects I am using here.
Here's the override:
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;
}
});
It uses the store.tree.nodeHash
object to iterate through all nodes against the filters rather than just the first child. It will accept a filter as a function or property/value pair. I suppose the clearFilter method could be worked over though to prevent another ajax call.
这篇关于Ext JS 4:过滤 TreeStore的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!