隨筆-124  評論-194  文章-0  trackbacks-0

          dojo提供了不錯的樹控件,但上下文菜單比較簡單,不能動態(tài)改變:比如我想根據(jù)不同節(jié)點顯示不同的上下文菜單就比較困難,根據(jù)多種實驗和查閱下面提供一種實現(xiàn)方式。在此過程中也學(xué)到不少東西。先把解決方案說一下,再把發(fā)現(xiàn)過程說一下:

          DOJO提供了AOP的方式來“注入”代碼,我們就把修改menu的代碼注入到TreeContextMenuV3里就可以了:
          在open事件前注入我們的代碼:

          dojo.event.connect("before", dojo.widget.byId("contextMenu1"), "open"this"onContextMenuOpen");

          注意before是表示在menu打開之前調(diào)用,其它關(guān)鍵字還可以是after,around。強(qiáng),贊一個!

          在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é)點來增刪菜單項了,context_menu成員是用來記錄加入過的菜單項,以免重復(fù)加入。
          另外,removeChild沒有destory掉菜單項,應(yīng)該可以重復(fù)使用。所以,我設(shè)想的實現(xiàn)是,在程序開頭將所有可能的菜單項動態(tài)創(chuàng)建好,存在一個MAP中,然后,在這里來動態(tài)加刪它們。


          下面是尋找解決方法的過程:

          剛開始時,我想是改變整個樹的菜單,確實也找到了可以編程改變它的方法:

          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。
          這樣雖然可以動態(tài)“加載”菜單了,可是沒有“時機(jī)”來加載新菜單,無法達(dá)到根據(jù)節(jié)點變化來做改變。


          隨后,我又想到重載,去創(chuàng)造這個“時機(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)其實很簡單,關(guān)鍵要注意它的namespace:
          dojo.require()語句的尋找方法是:
          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開頭時,它的尋找方法是:
          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同級就可以了。
          這個辦法我沒往下試,因為重載的是contextmenu,在它里面把它“整個自己”換成別的menu,我覺得是不可行的。而看半天代碼也沒找著在哪重載右鍵點擊這個事件。不過啟發(fā)我可以更換子item來解決。
          于是有了開頭的解決方案。

          posted on 2007-07-01 11:15 我愛佳娃 閱讀(2618) 評論(3)  編輯  收藏 所屬分類: AJAX

          評論:
          # re: 在dojo的TreeV3中實現(xiàn)動態(tài)的上下文菜單TreeContextMenuV3[未登錄] 2007-08-30 09:00 | 小強(qiáng)
          想問下你有沒有考慮 后臺如何來取得修改后的樹。即如何來取得整個樹的所有節(jié)點以及其之間的關(guān)系  回復(fù)  更多評論
            
          # re: 在dojo的TreeV3中實現(xiàn)動態(tài)的上下文菜單TreeContextMenuV3 2007-09-10 10:58 | 我愛佳娃
          DOJO太慢,最近在研究其它庫。
          不如試下YUI-EXT這個庫,誰用誰知道。  回復(fù)  更多評論
            
          # re: 在dojo的TreeV3中實現(xiàn)動態(tài)的上下文菜單TreeContextMenuV3 2007-12-21 11:24 | wudili
          兄弟,多謝,我想了3天了.
          甚至想過重寫,還是你牛!  回復(fù)  更多評論
            
          主站蜘蛛池模板: 新源县| 杭锦后旗| 八宿县| 孙吴县| 巴彦县| 台南县| 改则县| 五河县| 沁水县| 汉中市| 巴彦县| 永安市| 仁化县| 科尔| 富锦市| 鄢陵县| 黄龙县| 屏山县| 临湘市| 丰都县| 遵义县| 宁陵县| 佛山市| 社旗县| 四子王旗| 浙江省| 正定县| 衡水市| 历史| 旬邑县| 紫金县| 微山县| 平遥县| 永年县| 确山县| 黎平县| 广平县| 新沂市| 惠水县| 乌恰县| 广德县|