dojo 在dijit.树中搜索

rmbxnbpk  于 2022-12-16  发布在  Dojo
关注(0)|答案(1)|浏览(195)

在我的一个项目中,我使用了dijit.Tree控件。我需要在树中添加一个搜索,并且只显示那些包含搜索项的节点/叶。但是我似乎不知道如何实现这一点。有人能帮帮我吗?

wd2eg0qa

wd2eg0qa1#

我不能完全肯定你的问题是否完全正确,但它应该能给我们一个提示。
让我们使用参考文档示例作为补偿,有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;

接下来,在模型上设置一个新的查询-使用对象混合保留旧的查询。

treeModel.query = dojo.mixin(oQuery, { name: '*'+searchByName+'*' });

最后,通知模型及其树发生了更改-并重新查询可见项。

treeModel._requeryTop();

NB如果顶级项(ForestModel)不可见,则不会显示其子元素,即使搜索字符串与这些子元素匹配。(例如,如果查询与美国大陆不匹配,则不会显示亚拉巴马)

  • 编辑 *

由于OP有议程去'NB',这可能不适合需要100%,但它是什么dojo提供与dijit.Tree..因为它会得到相当漫长的过程,重新编码模型/存储查询,以包括父分支,直到根我不会这样做-但仍然有一些技巧;)

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);

相关问题