dojo提供了不錯(cuò)的樹(shù)控件,但上下文菜單比較簡(jiǎn)單,不能動(dòng)態(tài)改變:比如我想根據(jù)不同節(jié)點(diǎn)顯示不同的上下文菜單就比較困難,根據(jù)多種實(shí)驗(yàn)和查閱下面提供一種實(shí)現(xiàn)方式。在此過(guò)程中也學(xué)到不少東西。先把解決方案說(shuō)一下,再把發(fā)現(xiàn)過(guò)程說(shuō)一下:
DOJO提供了AOP的方式來(lái)“注入”代碼,我們就把修改menu的代碼注入到TreeContextMenuV3里就可以了:
在open事件前注入我們的代碼:
dojo.event.connect("before", dojo.widget.byId("contextMenu1"), "open", this, "onContextMenuOpen");
注意before是表示在menu打開(kāi)之前調(diào)用,其它關(guān)鍵字還可以是after,around。強(qiáng),贊一個(gè)!
在onContextMenuOpen函數(shù)中,做改變菜單的事情:

this.onContextMenuOpen = function (evt)
{
dojo.log.info ("before context open");
dojo.log.info (evt);
var m = dojo.widget.byId("contextMenu1");
dojo.log.info (m);
m.removeChild (dojo.widget.byId("treeContextMenuEdit"));
m.removeChild (dojo.widget.byId("treeContextMenuDown"));
m.removeChild (dojo.widget.byId("treeContextMenuCreate"));
m.removeChild (dojo.widget.byId("treeContextMenuCreate2"));


if (null == this.context_menu["MenuItem2"])
{

var id = dojo.widget.createWidget("MenuItem2",
{caption: "Page Info"});
dojo.log.info (id);
this.context_menu["MenuItem2"] = id;
m.addChild(id);
}
//m.destroyChildren ();
dojo.log.info (m);
//w.destory ();
};
在這里可以根據(jù)節(jié)點(diǎn)來(lái)增刪菜單項(xiàng)了,context_menu成員是用來(lái)記錄加入過(guò)的菜單項(xiàng),以免重復(fù)加入。
另外,removeChild沒(méi)有destory掉菜單項(xiàng),應(yīng)該可以重復(fù)使用。所以,我設(shè)想的實(shí)現(xiàn)是,在程序開(kāi)頭將所有可能的菜單項(xiàng)動(dòng)態(tài)創(chuàng)建好,存在一個(gè)MAP中,然后,在這里來(lái)動(dòng)態(tài)加刪它們。
下面是尋找解決方法的過(guò)程:
剛開(kāi)始時(shí),我想是改變整個(gè)樹(shù)的菜單,確實(shí)也找到了可以編程改變它的方法:
var ctxMenu = dojo.widget.byId("contextMenu");
var tree = dojo.widget.byId("phyTree");
dojo.log.info (ctxMenu);

ctxMenu.listenTree(tree);
ctxMenu.bindDomNode(tree.domNode);

關(guān)鍵是一句:bindDomNode。
這樣雖然可以動(dòng)態(tài)“加載”菜單了,可是沒(méi)有“時(shí)機(jī)”來(lái)加載新菜單,無(wú)法達(dá)到根據(jù)節(jié)點(diǎn)變化來(lái)做改變。
隨后,我又想到重載,去創(chuàng)造這個(gè)“時(shí)機(jī)”:
dojo.require ("dojo.widget.TreeContextMenuV3");

dojo.provide("mywidgets.MyTreeContextMenu");

dojo.widget.defineWidget(
// widget name and class
"mywidgets.MyTreeContextMenu",
// superclass
[dojo.widget.TreeContextMenuV3],


function()
{
dojo.log.info ("my context menu create1");
},
// properties and methods

{

open: function()
{
var result = dojo.widget.PopupMenu2.prototype.open.apply(this, arguments);
dojo.log.info ("my context menu create");

for(var i=0; i< this.children.length; i++)
{

/**//* notify children */

if (this.children[i].menuOpen)
{
this.children[i].menuOpen(this.getTreeNode());
}
}
return result;
}
}
);

這也是我第一次重載DOJO,發(fā)現(xiàn)其實(shí)很簡(jiǎn)單,關(guān)鍵要注意它的namespace:
dojo.require()語(yǔ)句的尋找方法是:
dojo.xxx => dojo/src/xxx.js
dojo.xxx.yyy => dojo/src/xxx/yyy.js
dojo.xxx.yyy.zzz => dojo/src/xxx/yyy/zzz.js
如果遇到不是dojo開(kāi)頭時(shí),它的尋找方法是:
example.xxx => dojo/../example/xxx.js
example.xxx.yyy => dojo/../example/xxx/yyy.js
example.xxx.yyy.zzz => dojo/../example/xxx/yyy/zzz.js
所以要把自己的代碼放到跟dojo同級(jí)就可以了。
這個(gè)辦法我沒(méi)往下試,因?yàn)橹剌d的是contextmenu,在它里面把它“整個(gè)自己”換成別的menu,我覺(jué)得是不可行的。而看半天代碼也沒(méi)找著在哪重載右鍵點(diǎn)擊這個(gè)事件。不過(guò)啟發(fā)我可以更換子item來(lái)解決。
于是有了開(kāi)頭的解決方案。
posted on 2007-07-01 11:15
我愛(ài)佳娃 閱讀(2613)
評(píng)論(3) 編輯 收藏 所屬分類(lèi):
AJAX