如何将dijit.Menu与dijit.Tree的特定节点关联(绑定)

时间:2010-07-09 20:24:37

标签: dojo

我已经能够将一个带有两个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);

                }

            });
        }
    });

5 个答案:

答案 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);

另一种解决方案是:

  1. 更改数据存储 - 添加项目“Continents”
  2. 指示所有大洲都是数据存储中此项目的子项
  3. showRoot="false"参数添加到树窗口小部件
  4. 更改属性query =' {'name': 'Continents'}'
  5. 的值模型

    但是有许多在线演示,例如:

答案 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>