我已经能够将一个带有两个MenuItem的简单dijit.Menu绑定到一个dijit.Tree与Menu.bindDomNode(Tree.domNode)的节点,但我想改进哪些节点获取上下文菜单并且我正在使用从Tree项目中获取domNodes以将菜单绑定到。我希望有一个更简单的方法吗?
datStore = this.DataStore;
mdl = this.Model;
tree = this.Tree;
datStore.fetch({
query: { nodeType: "ROOT" },
onItem: function(item, request) {
dojo.forEach(datStore.getValues(item, "children"), function(childItem) {
var itemNode = tree.getNodesByItem(mdl.getIdentity(childItem));
console.log(itemNode): //returns the widget, and the widget has a domNode property that seems ok with firebug traversing of the itemNode object, though the div value is 'dimmed' in firebug (not valid node yet in the DOM?)
console.log(itemNode.domNode);//returns 'undefined', so the binding below does not work
if (childItem.nodeType == "MATCHED_VALUE") {
Menu.bindDomNode(itemNode.domNode);
}
});
}
});
答案 0 :(得分:7)
如果您不喜欢使用像“_openMyself”这样的伪私有方法,也可以使用菜单的onFocus事件。您应该右键单击更改当前选定的节点。
var tree = new dijit.Tree({
onMouseDown:function(ev,node){
if(ev.button==2){ // right-click
var here=dijit.getEnclosingWidget(ev.target);
this.set('selectedNode',here);
}
}
});
var menuItem=new dijit.MenuItem({...});
var myMenu = new dijit.Menu({
onFocus:function(){
var selected=tree.selectedItem;
// do stuff here like:
menuItem.attr('disabled',(selected.children)?true:false);
}
});
myMenu.addChild(menuItem);
myMenu.bindDomNode(tree.domNode);
由于众所周知缺少Dojo文档,我花了几个小时的试验和错误才发现。这就是为什么我在问题发布2年后在这里发帖。
答案 1 :(得分:2)
我做了这样的事情:
<div dojoType="dijit.Tree" id="tree" model="continentModel" openOnClick="true">
<script type="dojo/connect">
var menus = {
continent : dijit.byId('treeMenuContinent'),
country : dijit.byId('treeMenuCountry'),
city : dijit.byId('treeMenuCity')
};
this.onOpen = function(item, node){
function bindProperMenu( node, item ) {
var m, type;
item = item || {};
for(m in menus) {
menus[m].unBindDomNode(node);
}
type = continentStore.getValue(item, 'type');
if (type) {
menus[type].bindDomNode(node);
}
}
// the store object has a `root 'field
// for which we do not want to call the menu
if (!item.root) {
var children = node.containerNode.childNodes,
n = children.length,
thisWidget;
while(n--) {
// add the appropriate menu for children
thisWidget = dijit.getEnclosingWidget(children[n]);
bindProperMenu(thisWidget.domNode, thisWidget.item);
}
// attach menu to the current node
bindProperMenu(node.domNode, item);
} else {
// we're on the "Continents" node, add artificially
menus['continent'].bindDomNode(this.domNode);
}
}
</script>
</div>
进一步解释here。我知道它很精彩 - 对不起:P
在我们的树中,具有“Continents”标签的节点不存在(即它不在数据存储中)。树中没有与此项对应的项。因此,这个黑客需要一个严格的任务:
menus['continent'].bindDomNode(this.domNode);
另一种解决方案是:
showRoot="false"
参数添加到树窗口小部件query =' {'name': 'Continents'}'
但是有许多在线演示,例如:
答案 2 :(得分:1)
你的方式看起来不错。您还可以保持绑定到Tree节点本身,但覆盖Menu._openMyself()。 test_Tree.html中有类似的代码:
dojo.connect(menu, "_openMyself", this, function(e){
// get a hold of, and log out, the tree node that was the source of this open event
var tn = dijit.getEnclosingWidget(e.target);
console.debug(tn);
// now inspect the data store item that backs the tree node:
console.debug(tn.item);
// contrived condition: if this tree node doesn't have any children, disable all of the menu items
dojo.forEach(menu.getChildren(), function(i){ i.set('disabled', !tn.item.children); });
// IMPLEMENT CUSTOM MENU BEHAVIOR HERE
});
但是,我认为这不一定比你的方式更好。
答案 3 :(得分:1)
我相信问题是;
itemNode.domNode
因为`itemNode'是一个数组,根据文档: http://dojotoolkit.org/api/1.6/dijit.Tree/getNodesByItem
使用: itemNode [0] .domNode
答案 4 :(得分:0)
下面的代码显示了一个树节点的单击菜单
<!DOCTYPE html>
<html >
<head>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.7.2/dijit/themes/claro/claro.css" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/resources/dojo.css" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dijit/themes/tundra/tundra.css" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
<script>require(["dojo/parser", "dojo/store/Memory", "dijit/Menu", "dijit/MenuItem", "dijit/tree/ObjectStoreModel", "dijit/Tree"]);</script>
<script type="text/javascript">
dojo.require("dojo.data.ItemFileReadStore");
dojo.require( "dijit.Tree" );
dojo.require("dijit.Menu");
dojo.require("dijit.MenuItem");
dojo.require("dijit.tree.ForestStoreModel");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.Tree");
var rawdata = [ {
label: 'Vegetables',
id: '1',
children: [ { label: 'tomato', id: '1.1' }, { label: 'onion', id: '1.2' } ]
}, {
label: 'Fruits',
id: '2',
children: [
{ id: '2.1', label: 'Apple' },
{ id: '2.3', label: 'Grapes' }
]
} ];
function prepare(){
var store = new dojo.data.ItemFileReadStore({
data: { identifier: 'id', label : 'label', items: rawdata }
});
var treeModel = new dijit.tree.ForestStoreModel({ store: store });
var treeControl = new dijit.Tree({
model: treeModel,
showRoot: false,
_createTreeNode: function(/*Object*/ args){
var tnode = new dijit._TreeNode(args);
tnode.labelNode.innerHTML = args.label;
return tnode;
}
}, "treeOne" );
var AllMenu = new dijit.Menu({ style: "display: none;"});
var menuItem1 = new dijit.MenuItem({
label: "Add Instance",
iconClass:"",
style:"background-color:#4B57FA",
onClick: function(){ alert('started'); }
});
AllMenu.addChild(menuItem1);
AllMenu.bindDomNode(treeControl.domNode);
}
dojo.ready(prepare);
</script>
</head>
<body class="claro">
<div id="treeOne"> </div>
</body>
</html>