我想在Ext.Data.TreeStore上应用过滤器。树商店正在使用的模型具有名称为“ID”的属性。基于这个'ID'我想在树存储上应用过滤器。
我查看了以下链接:
但这些选项无效。
在商店'加载'事件中,我添加了以下代码。
'load': function (thisStore, records, successful, eOpts) {
var v = 'Product';
var count = 0;
thisStore.filterBy(function (record) {
count++;
return record.data.ID == v;
});
alert(count);
}
但是计数总是为0。
我的树看起来像这样:
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 200,
height: 150,
store: store,
rootVisible: false,
renderTo: Ext.getBody(),
plugins:[Ext.create('plugin.treefilter',{
pluginId: 'treefilter',
allowParentFolders: true
})]
});
插件:
Ext.define('Ext.ux.TreeFilter', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.treefilter',
collapseOnClear: false, // collapse all nodes when clearing/resetting the filter
allowParentFolders: false, // allow nodes not designated as 'leaf' (and their child items) to be matched by the filter
init: function (tree) {
var me = this;
me.tree = tree;
tree.filter = Ext.Function.bind(me.filter, me);
tree.clearFilter = Ext.Function.bind(me.clearFilter, me);
tree.filterBy = Ext.Function.bind(me.filterBy,me);
},
filter: function (value, property, re) {
var me = this;
if (Ext.isEmpty(value)) { // if the search field is empty
me.clearFilter();
return;
}
property = property || 'text';// property is optional - will be set to the 'text' propert of the treeStore record by default
re = re || new RegExp(value, "ig"); // the regExp could be modified to allow for case-sensitive, starts with, etc.
// iterate over all nodes in the tree in order to evalute them against the search criteria
me.filterBy(function(node){
return node.get(property).match(re);// if the node matches the search criteria and is a leaf (could be modified to searh non-leaf nodes)
});
},
filterBy: function (fn,scope){
var me = this,
tree = me.tree,
matches = [], // array of nodes matching the search criteria
root = tree.getRootNode(), // root node of the tree
visibleNodes = [], // array of nodes matching the search criteria + each parent non-leaf node up to root
viewNode;
if (!fn) { // if no fn defined
me.clearFilter();
return;
}
tree.expandAll(); // expand all nodes for the the following iterative routines
//fn.call(scope || me, record)
root.cascadeBy(function (node){
if(fn.call(scope || me, node)){
matches.push(node);// add the node to the matches array
}
});
if (me.allowParentFolders === false) { // if me.allowParentFolders is false (default) then remove any non-leaf nodes from the regex match
Ext.each(matches, function (match) {
if (match !== undefined) {
if (!match.isLeaf()) {
Ext.Array.remove(matches, match);
}
}
});
}
Ext.each(matches, function (item, i, arr) { // loop through all matching leaf nodes
root.cascadeBy(function (node) { // find each parent node containing the node from the matches array
if (node.contains(item) === true) {
visibleNodes.push(node); // if it's an ancestor of the evaluated node add it to the visibleNodes array
}
});
/* Commented out because this shows all children whether or not they pass the filter
if (me.allowParentFolders === true && !item.isLeaf()) { // if me.allowParentFolders is true and the item is a non-leaf item
item.cascadeBy(function (node) { // iterate over its children and set them as visible
visibleNodes.push(node);
});
}
*/
visibleNodes.push(item); // also add the evaluated node itself to the visibleNodes array
});
root.cascadeBy(function (node) { // finally loop to hide/show each node
viewNode = Ext.fly(tree.getView().getNode(node)); // get the dom element assocaited with each node
if (viewNode) { // the first one is undefined ? escape it with a conditional
viewNode.setVisibilityMode(Ext.Element.DISPLAY); // set the visibility mode of the dom node to display (vs offsets)
viewNode.setVisible(Ext.Array.contains(visibleNodes, node));
}
});
},
clearFilter: function () {
var me = this,
tree = this.tree,
root = tree.getRootNode(),
viewNode;
if (me.collapseOnClear) {
tree.collapseAll();
} // collapse the tree nodes
root.cascadeBy(function (node) { // final loop to hide/show each node
viewNode = Ext.fly(tree.getView().getNode(node)); // get the dom element assocaited with each node
if (viewNode) { // the first one is undefined ? escape it with a conditional and show all nodes
viewNode.show();
}
});
}
});
请建议我需要做出的更改,以确保我可以过滤TreeStore。
答案 0 :(得分:1)
你必须自己实现一些东西......这是一个可行的filterBy
方法。请注意,与常规存储过滤器相反,此过滤器不会保留已过滤节点的引用(因此,不可能使用clearFilter
方法)。如果你需要任何花哨的东西,你就必须适应。
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{ text: "detention", leaf: true },
{ text: "homework", expanded: true, children: [
{ text: "book report", leaf: true },
{ text: "algebra", leaf: true}
] },
{ text: "buy lottery tickets", leaf: true }
]
}
});
var tree = Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 200,
height: 150,
store: store,
rootVisible: false,
renderTo: Ext.getBody()
/**
* Filters the tree recursively with the given function.
*
* @param {Function} fn
* @param {Object} [scope]
*/
,filterBy: function(fn, scope) {
scope = scope || this;
function applyFilter(node) {
var out = [];
Ext.each(node.childNodes, function(child) {
if (fn.call(scope, child)) {
applyFilter(child);
} else {
// we can't remove child right away, that would
// kill the loop
out.push(child);
}
});
Ext.each(out, function(child) {
// destroy, and suppressEvent
node.removeChild(child, true, true);
});
}
applyFilter(this.getRootNode());
}
});
// example
tree.filterBy(function(record) {
return record.get('text').indexOf('o') !== -1;
});