【发布时间】:2016-10-13 16:07:38
【问题描述】:
我需要过滤树(通过将文本与节点属性进行比较来搜索节点)。
这个fiddle 正是我所需要的,但它似乎不适用于 ExtJS 6.2。
在试图找出我的代码有什么问题之后,我决定简单地将 fiddle 中的框架版本从 4.2.1(默认)更改为 6.2.981 经典灰色,并且可以看到代码已过时(删除所有节点或任意数量我不明白为什么)。
有人可以验证该代码并告诉我如何将其移植到 v6.2 吗?
编辑:
差不多了。这段代码正在完成这项工作,但在深层 2 中停止,而不是所有树:JSFiddle
Ext.define('TreeFilter', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.treefilter',
collapseOnClear: true, // 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);
},
filter: function(value, property, re) {
var me = this,
tree = me.tree,
matches = [], // array of nodes matching the search criteria
root = tree.getRootNode(), // root node of the tree
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.
visibleNodes = [], // array of nodes matching the search criteria + each parent non-leaf node up to root
viewNode;
if (Ext.isEmpty(value)) { // if the search field is empty
me.clearFilter();
return;
}
tree.expandAll(); // expand all nodes for the the following iterative routines
// iterate over all nodes in the tree in order to evalute them against the search criteria
root.cascadeBy(function(node) {
if (node.get(property).match(re)) { // if the node matches the search criteria and is a leaf (could be modified to searh non-leaf nodes)
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.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
}
});
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();
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();
}
});
}
});
// EXAMPLE
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "detention",
leaf: true
}, {
text: "homework",
expanded: false,
children: [{
text: "book report",
leaf: true
}, {
text: "algebra",
leaf: true
}]
}, {
text: "chores",
expanded: false,
children: [{
text: "do homework",
leaf: true
}, {
text: "walk dog",
leaf: true
}, {
text: "clean room",
leaf: true
}, {
text: "wash dishes",
leaf: true
}, {
text: "laundry",
leaf: true
}]
}, {
text: "buy lottery tickets",
leaf: true
}, {
text: "take over world",
leaf: true
}, {
text: "Sencha",
expanded: false,
children: [{
text: "Touch",
expanded: false,
children: [{
text: 'Viewport',
leaf: true
}, {
text: 'Panel',
leaf: true
}, {
text: 'Carousel',
leaf: true
}]
}, {
text: "ExtJS",
expanded: false,
children: [{
text: 'viewport.Viewport',
leaf: true
}, {
text: 'panel.Panel',
leaf: true
}, {
text: 'tree.Panel',
leaf: true
}]
}]
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 200,
height: 150,
store: store,
rootVisible: false,
renderTo: Ext.getBody(),
plugins: [{
ptype: 'treefilter',
allowParentFolders: true
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'trigger',
triggerCls: 'x-form-clear-trigger',
onTriggerClick: function() {
this.reset();
this.focus();
},
listeners: {
change: function(field, newVal) {
var tree = field.up('treepanel');
tree.filter(newVal);
},
buffer: 250
}
}]
}]
});
【问题讨论】:
-
为什么是
Ext.data.NodeStore而不是Ext.data.TreeStore?