Искать в dijit.Tree

В одном из моих проектов я использую dijit.Tree control. Мне нужно добавить поиск в дерево и показать только те узлы / листья, в которых есть искомый термин. Однако я не могу понять, как этого можно достичь. Кто-нибудь может мне помочь?

1 ответ

Решение

Я не совсем уверен, что ваш вопрос полностью, но он должен дать подсказку, а идти.

Давайте использовать пример справочной документации в качестве смещения, есть 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();

NB. Если элемент верхнего уровня (для 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);
Другие вопросы по тегам