【问题标题】:Dijit Tree filtering and search not working on ObjectStoreModelDijit 树过滤和搜索不适用于 ObjectStoreModel
【发布时间】:2015-10-24 12:05:58
【问题描述】:

我创建了一个 dijit 树和一个文本框,我想根据文本框中提供的关键字过滤树节点。我实施了另一个问题中提供的解决方案,但它似乎不起作用。当用户在文本框中输入一些单词时,树会重新填充相同的数据。

dijit.Tree search and refresh

以下是我的代码:

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",
        parent: "0"
    }, {
        id: "3",
        name: "Diagnosis",
        parent: "0"
    }, {
        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/

树和文本框渲染得很好,只有搜索不起作用,有什么建议吗?还有为什么 EXPAND (+) 符号与叶节点一起显示?

【问题讨论】:

    标签: tree dojo store dijit.tree


    【解决方案1】:

    我已经为模型的数据添加了一个自定义属性。它被命名为keep,负责过滤。每一项数据都有这个属性。如果keeptrue,则该项目将可见。如果keepfalse,则该项目将被隐藏。
    当输入模糊时,keep 会更新并重新创建树。
    为了保持树形结构,如果一个项目与文本匹配,我们递归地将其所有父项标记为keep,即使它们不匹配(否则您将看不到项目本身)
    我为重新创建树评论了一些不需要的行。

    如您所见,keep 用于

        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", "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() {
            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",
                name: "Root Node",
                parent: null,
                keep: true
            }, {
                id: "1",
                name: "File",
                parent: "0",
                keep: true
            }, {
                id: "2",
                name: "System",
                parent: "0",
                keep: true
            }, {
                id: "3",
                name: "Diagnosis",
                parent: "0",
                keep: true
            }, {
                id: "4",
                name: "Management",
                parent: "0",
                keep: true
            },
            {
                id: "5",
                name: "New",
                parent: "1",
                keep: true
            },
            {
                id: "6",
                name: "Open",
                parent: "1",
                keep: true
            },
            {
                id: "7",
                name: "Import",
                parent: "1",
                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>

    【讨论】:

    • 代码适用于单级菜单。当我添加子节点时,它不会显示它们,因为“mayHaveChildren”返回 false。但是,如果我返回 true 而不是 false,那么它会显示子节点,但过滤器仅适用于顶级节点。如果可以显示和过滤子节点,那么我的问题将解决并且我可以接受答案。在此处查看更新的代码:jsfiddle.net/xLfdhnrf/26 通过在“mayHaveChildren”中返回“true”来检查以显示树的子节点。
    • 更新后的代码满足所有要求。感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 2018-09-13
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 2019-11-11
    相关资源
    最近更新 更多