在我的一个项目中,我使用 dijit.Tree 控件。我需要向树中添加搜索并仅显示其中包含搜索词的那些节点/叶子。但是,我似乎无法弄清楚如何实现这一目标。有人可以帮我吗?
问问题
2619 次
1 回答
0
我不完全确定你的问题完全但它应该给出提示。
让我们使用参考文档示例作为偏移量,有 1) 存储 2) 模型和 3) 树
var store = new ItemFileReadStore({
url: "{{dataUrl}}/dijit/tests/_data/countries.json"
});
var treeModel = new ForestStoreModel({
store: store,
query: {"type": "continent"}, // note, this bit
rootId: "root",
rootLabel: "Continents",
childrenAttrs: ["children"]
});
new Tree({
model: treeModel
}, "treeOne");
如此解释上述内容;您已加载所有已知的国家和大洲,但“用户”已选择仅通过在模型上使用查询来显示大洲 - 然后层次结构以树结构表示。
您想要一个具有搜索功能的文本框,所以我们连接到 onChange
new dijit.form.TextBox({
onChange: function() {
...
}
});
第一点,获取变量
var searchByName = this.get("value");
var oQuery = treeModel.query;
接下来,在模型上设置一个新查询 - 使用对象 mixin 保留旧查询
treeModel.query = dojo.mixin(oQuery, { name: '*'+searchByName+'*' });
最后,通知模型及其树发生了变化 - 并重新查询可见项。
treeModel._requeryTop();
注意如果顶级项目(For ForestModel)不可见,则不会显示其任何子元素,即使搜索字符串与那些匹配。(例如,如果查询不匹配美国大陆,则不显示阿拉巴马州)
编辑
由于 OP 有通过“NB”的议程,这可能不适合 100% 的需求,但它是 dojo 提供的 dijit.Tree.. 因为重新编码模型/存储查询以包含父分支将需要相当长的过程直到 root 我不会在这里这样做 - 但仍然有一些技巧;)
var tree = new dijit.Tree( {
/**
* Since TreeNode has a getParent() method, this abstraction could be useful
* It sets the dijit.reqistry id into the item-data, so one l8r can get parent items
* which otherwise only can be found by iterating everything in store, looking for item in the parent.children
*
*/
onLoad : function() {
this.forAllNodes(function(node) {
// TreeNode.item <-- > store.items hookup
node.item._NID = node.domNode.id
});
},
/* recursive iteration over TreeNode's
* Carefull, not to make (too many) recursive calls in the callback function..
* fun_ptr : function(TreeNode) { ... }
*/
forAllNodes : function(parentTreeNode, fun_ptr) {
parentTreeNode.getChildren().forEach(function(n) {
fun_ptr(n);
if(n.item.children) {
n.tree.forAllNodes(fun_ptr);
}
})
}
});
(未经测试,但可能只是工作)示例:
// var 'tree' is your tree, extended with
tree.forAllNodes = function(parentTreeNode, fun_ptr) {
parentTreeNode.getChildren().forEach(function(n) {
fun_ptr(n);
if(n.item.children) {
n.tree.forAllNodes(fun_ptr);
}
})
};
// before anything, but the 'match-all' query, run this once
tree.forAllNodes(tree.rootNode, function(node) {
// TreeNode.item <-- > store.items hookup
node.item._NID = node.domNode.id
});
// hopefully, this in end contains top-level items
var branchesToShow = []
// run fetch every search (TextBox.onChange) with value in query
tree.model.store.fetch(query:{name:'Abc*'}, onComplete(function(items) {
var TreeNode = null;
dojo.forEach(items, function(item) {
TreeNode = dijit.byId(item._NID+'');
while(TreeNode.getParent()
&& typeof TreeNode.getParent().item._RI == 'undefined') {
TreeNode = TreeNode.getParent();
}
branchesToShow.push(TreeNode.item);
});
}});
// Now... If a success, try updating the model via following
tree.model.onChildrenChange(tree.model.root, branchesToShow);
于 2012-07-23T20:40:38.407 回答