2015-08-02 4 views
5

Я создал дерево диджитов и текстовое поле, и я хочу отфильтровать узлы дерева на основе ключевых слов, предоставленных в текстовом поле. Я реализовал решение, предоставленное в другом вопросе, но оно, похоже, не работает. Когда пользователь вводит какое-либо слово в текстовое поле, дерево повторно заполняется одними и теми же данными.Dijit Tree фильтрация и поиск не работают на ObjectStoreModel

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 (+) показывает с листовыми узлами?

Snapshot of Filterable Tree

ответ

6

Я добавил пользовательское свойство к данным модели. Он называется keep, и он отвечает за фильтрацию. Каждый элемент данных имеет это свойство. Если keep - true, элемент будет виден. если keep - false, объект будет скрыт.
Когда размывается вход, 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>

+0

Код отлично подходит для меню одного уровня работы. Когда я добавляю дочерние узлы, он не отображает их, потому что «mayHaveChildren» возвращает false. Однако, если я возвращаю true вместо false, тогда он отображает дочерние узлы, но фильтр работает только для узлов верхнего уровня. Если дочерние узлы могут отображаться и фильтроваться, моя проблема будет решена, и я могу принять ответ. См. Обновленный код здесь: http://jsfiddle.net/xLfdhnrf/26/ Проверьте, вернув «true» в «mayHaveChildren» для отображения дочерних узлов дерева. –

+0

@ asim-ishaq, отредактировал ответ – ben

+0

Обновленный код соответствует всем требованиям. Спасибо за ответ. –