我创建了一个dijit树和一个文本框,我想根据文本框中提供的关键字过滤树节点.我实现了另一个问题中提供的解决方案,但它似乎不起作用.当用户在文本框中输入某个单词时,将使用相同的数据重新填充树.
以下是我的代码:
require(["dijit/form/TextBox","dojo/store/Memory","dijit/tree/ObjectStoreModel","dijit/Tree","dojo/domReady!"],function(TextBox,MemoryStore,ObjectStoreModel,Tree) { var searchBox = new TextBox({ placeHolder: "[ Type here to search ]" },"searchBox"); searchBox.on("blur",function() { tree.model.store.query({ name: "*" + searchBox.value + "*" }); /*the below approach has been taken from the other question*/ tree.model.store.clearOnClose = true; /*tree.model.store.close(); //This is not working?*/ delete tree._itemNodesMap; tree._itemNodesMap = {}; tree.rootNode.state = "UNCHECKED"; delete tree.model.root.children; tree.model.root.children = null; tree.rootNode.destroyRecursive(); tree.model.constructor(tree.model) tree.postMixInProperties(); tree._load(); }); var store = new MemoryStore({ idProperty: "id",getChildren: function(object) { return this.query({ parent: object.id }); },data: [{ id: "0",name: "Root Node",parent: null },{ id: "1",name: "File",parent: "0" },{ id: "2",name: "System",{ id: "3",name: "Diagnosis",{ id: "4",name: "Management",parent: "0" }] }); var model = new ObjectStoreModel({ store: store,query: { id: "0" } }); var tree = new Tree({ model: model,showRoot: false },"treeDiv"); tree.startup(); });
请参阅JSFIDDLE中的示例代码:
http://jsfiddle.net/xLfdhnrf/16/
解决方法
我已经为模型的数据添加了一个自定义属性.它被命名为keep,它负责过滤.每项数据都具有此属性.如果保持为真,则该项目将可见.如果keep为false,则该项目将被隐藏.
当输入模糊时,保持更新并重新创建树.
为了保持树形结构,如果一个项目与文本匹配,我们递归地将它的所有父项标记为保持,即使它们不匹配(否则你不会看到项目本身)
我为树重新创建了一些不需要的行.
当输入模糊时,保持更新并重新创建树.
为了保持树形结构,如果一个项目与文本匹配,我们递归地将它的所有父项标记为保持,即使它们不匹配(否则你不会看到项目本身)
我为树重新创建了一些不需要的行.
如您所见,保留用于
getChildren: function(object) { return this.query({ parent: object.id,keep: true }); },
这就是树被过滤的方式.
我在模型中创建了一个方法mayHaveChildren.如果此方法返回true,则表示您具有可扩展节点.如果返回false,则表示节点正常.有关详情,请参见http://dojotoolkit.org/reference-guide/1.10/dijit/tree/Model.html.
mayHaveChildren返回值基于商店查询.
最后,我使用正则表达式而不是普通字符串,因此匹配不区分大小写.
require(["dijit/form/TextBox",Tree) { var searchBox = new TextBox({ placeHolder: "[ Type here to search ]" },"searchBox"); searchBox.on("blur",function() { var includeParent = function(itemId) { tree.model.store.query({ id: itemId }).forEach(function(item) { item.keep = true; //and we include all parent tree includeParent(item.parent); }); } //reset all node,first we exlude them all tree.model.store.query().forEach(function(item) { item.keep = false; }); //then we include only the one matching tree.model.store.query({ name: new RegExp('.*' + searchBox.value + '.*','i') }).forEach(function(item) { item.keep = true; //and we include all parent tree includeParent(item.parent); }); //delete tree._itemNodesMap; //tree._itemNodesMap = {}; //tree.rootNode.state = "UNCHECKED"; //delete tree.model.root.children; //tree.model.root.children = null; tree.rootNode.destroyRecursive(); tree.model.constructor(tree.model) tree.postMixInProperties(); tree._load(); }); var store = new MemoryStore({ idProperty: "id",getChildren: function(object) { return this.query({ parent: object.id,keep: true }); },data: [{ id: "0",parent: null,keep: true },{ id: "1",parent: "0",{ id: "2",{ id: "3",{ id: "4",{ id: "5",name: "New",parent: "1",{ id: "6",name: "Open",{ id: "7",name: "Import",keep: true }] }); var model = new ObjectStoreModel({ store: store,query: { id: "0" },mayHaveChildren: function (item) { return store.query({parent: item.id}).length > 0; } }); var tree = new Tree({ model: model,showRoot: false },"treeDiv"); tree.startup(); });
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script> <link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css"> <body class="claro"> <div id="searchBox"></div> <div id="treeDiv"></div> </div>