私のプロジェクトの 1 つで、dijit.Tree コントロールを使用しています。ツリーに検索を追加し、検索された用語を含むノード/リーフのみを表示する必要があります。しかし、私はそれがどのように達成できるかを理解できないようです。誰でも私を助けてもらえますか?
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();
注: 最上位のアイテム (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);