云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Extjs Tree + JSON + Struts2

          Posted on 2008-02-19 09:27 云自無心水自閑 閱讀(43656) 評論(49)  編輯  收藏 所屬分類: Java心得體會Struts2AjaxExtjs
          最近嘗試用extjs來展示樹狀菜單。著實花了一番功夫。樹狀菜單的菜單項需要動態加載,而目前版本的extjs中只支持JSON格式的數據。查了一些資 料,決定使用struts2的json-plugin。首先按照例子做了一個,但是結果就是不成功,界面上只出來了一個js中生成的root節點,不能加 載從后臺生成的數據。研究后發現是數據格式有問題。使用json-plugin生成的數據格式如下:
          {"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}
          而extjs需要的數據格式如下:
          [{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}]
          區別很小,就只相差最外面的兩個方括號。但是少了這兩個方括號,在json中,含義迥然不同,前者表示一個對象,而后者表示一個數組。而extjs中 tree的dataloader需要的數據必須是一個數組。而這樣的數據格式是json-plugin自動生成的,無法改變。所以,我最后放棄了json -plugin,轉而使用json-lib來解決這個問題。
          1. 下載json-lib, http://json-lib.sourceforge.net/
          2. lib目錄下的jar文件清單:
          commons-beanutils-1.7.0.jar
          commons-collections-3.2.jar
          commons-digester-1.6.jar
          commons-lang-2.3.jar
          commons-logging-1.1.jar
          dom4j-1.6.1.jar
          ezmorph-1.0.4.jar
          freemarker-2.3.8.jar
          javassist-3.8.1.jar
          json-lib-2.2.1-jdk15.jar
          log4j-1.2.13.jar
          ognl-2.6.11.jar
          struts2-core-2.0.11.jar
          xml-apis-1.0.b2.jar
          xwork-2.0.4.jar


          首先配置web.xml
          <?xml version="1.0" encoding="UTF-8"?>
          <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
            xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee
              http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
          >
            
          <welcome-file-list>
              
          <welcome-file>index.jsp</welcome-file>
            
          </welcome-file-list>
            
          <filter>
              
          <filter-name>struts2</filter-name>
              
          <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
            
          </filter>

            
          <filter-mapping>
              
          <filter-name>struts2</filter-name>
              
          <url-pattern>/*</url-pattern>
            
          </filter-mapping>
          </web-app>

          然后是struts.xml
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE struts PUBLIC
              "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
              "http://struts.apache.org/dtds/struts-2.0.dtd"
          >
             
          <struts>
              
          <constant name="struts.devMode" value="true"/>
              
          <constant name="struts.i18n.encoding" value="UTF-8"/>
              
          <package name="person" extends="struts-default">
                  
          <action name="menus" method="execute" class="com.lab.MenuAction">
                      
          <result>/menu.jsp</result>
                  
          </action>
              
          </package>
          </struts>

          3. 樹的節點模型(省略了getter,setter)
          public class Menu {
              
          private int id;
              
          private String text;
              
          private boolean leaf;
              
          private String cls;
              
          private List<Menu> children;
          }

          4. action
          package com.lab;

          import java.util.ArrayList;
          import java.util.List;

          import net.sf.json.JSONArray;

          public class MenuAction {
              
          private String menuString;
             
              
          private List<Menu> menus;
             
              
          public String execute() {

                  menus 
          = new ArrayList<Menu>();
                 
                  Menu benz 
          = new Menu();
                  benz.setText(
          "Benz");
                  benz.setCls(
          "folder");
                  benz.setLeaf(
          false);
                  benz.setId(
          10);
                  menus.add(benz);
                 
                  List
          <Menu> benzList = new ArrayList<Menu>();
                  benz.setChildren(benzList);
                 
                  Menu menu;
                  menu 
          = new Menu();
                  menu.setText(
          "S600");
                  menu.setCls(
          "file");
                  menu.setLeaf(
          true);
                  menu.setId(
          11);
                  benzList.add(menu);
                  menu 
          = new Menu();
                  menu.setText(
          "SLK200");
                  menu.setCls(
          "file");
                  menu.setLeaf(
          true);
                  menu.setId(
          12);
                  benzList.add(menu);
                 
                  Menu bmw 
          = new Menu();
                  bmw.setText(
          "BMW");
                  bmw.setCls(
          "folder");
                  bmw.setLeaf(
          false);
                  bmw.setId(
          20);
                  menus.add(bmw);
                 
                  List
          <Menu> bmwList = new ArrayList<Menu>();
                  bmw.setChildren(bmwList);
                 
                  menu 
          = new Menu();
                  menu.setText(
          "325i");
                  menu.setCls(
          "file");
                  menu.setLeaf(
          true);
                  menu.setId(
          21);
                  bmwList.add(menu);
                 
                  menu 
          = new Menu();
                  menu.setText(
          "X5");
                  menu.setCls(
          "file");
                  menu.setLeaf(
          true);
                  menu.setId(
          22);
                  bmwList.add(menu);
                 
                  JSONArray jsonObject 
          = JSONArray.fromObject(menus);
                  
          try {
                      menuString 
          = jsonObject.toString();
                  } 
          catch (Exception e) {
                      menuString 
          = "ss";
                  }

                  
          return "success";
              }

              
          public String getMenuString() {
                  
          return menuString;
              }

              
          public void setMenuString(String menuString) {
                  
          this.menuString = menuString;
              }
          }

          5. menu.jsp
          <%@ taglib prefix="s" uri="/struts-tags" %>
          <s:property value="menuString" escape="false"/>

          6. html頁面和js
          我使用的就是extjs的example中的reorder.html和reorder.js,更改了reorder.js中treeloader的dataurl: menus.action
          <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
          <title>Reorder TreePanel</title>
          <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />

              
          <!-- GC -->
               
          <!-- LIBS -->
               
          <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>
               
          <!-- ENDLIBS -->
           
              
          <script type="text/javascript" src="extjs/ext-all.js"></script>
          <script type="text/javascript" src="reorder.js"></script>

          <!-- Common Styles for the examples -->
          <link rel="stylesheet" type="text/css" href="extjs/resources/css/example.css" />
          </head>
          <body>
          <script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->
          <h1>Drag and Drop ordering in a TreePanel</h1>
          <p>This example shows basic drag and drop node moving in a tree. In this implementation there are no restrictions and 
          anything can be dropped anywhere except appending to nodes marked 
          &quot;leaf&quot; (the files). <br></p>
          <p>Drag along the edge of the tree to trigger auto scrolling while performing a drag and drop.</p>
          <p>In order to demonstrate drag and drop insertion points, sorting was <b>not</b> enabled.</p>
          <p>The data for this tree is asynchronously loaded with a JSON TreeLoader.</p>
          <p>The js is not minified so it is readable. See <href="reorder.js">reorder.js</a>.</p>

          <div id="tree-div" style="overflow:auto; height:300px;width:250px;border:1px solid #c3daf9;"></div>

          </body>
          </html>



          js:
          /*
           * Ext JS Library 2.0.1
           * Copyright(c) 2006-2008, Ext JS, LLC.
           * licensing@extjs.com
           *
           * http://extjs.com/license
           
          */

          Ext.onReady(
          function(){
              
          // shorthand
              var Tree = Ext.tree;
             
              
          var tree = new Tree.TreePanel({
                  el:'tree
          -div',
                  autoScroll:
          true,
                  animate:
          true,
                  enableDD:
          true,
                  containerScroll: 
          true,
                  loader: 
          new Tree.TreeLoader({
                      dataUrl:'http:
          //localhost:8080/lab/menus.action'
                  })
              });

              
          // set the root node
              var root = new Tree.AsyncTreeNode({
                  text: 'Ext JS',
                  draggable:
          false,
                  id:'source'
              });
              tree.setRootNode(root);

              
          // render the tree
              tree.render();
              root.expand();
          });

          我已經上傳了完整的War文件(包含所有源代碼),見:Extjs Tree + JSON + Struts2 的所有示例源代碼和war文件下載




          評論

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-02-19 10:41 by 久城
          哈哈學習了!~返回JSON對象的時候,的確需要注意。

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-02-19 14:24 by altuure
          nice tutorial

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-02-20 16:59 by xt
          請教一個問題怎樣將樹下的欄目加上鏈接?
          /*
          * Ext JS Library 2.0
          * Copyright(c) 2006-2007, Ext JS, LLC.
          * licensing@extjs.com
          *
          * http://extjs.com/license
          */

          Ext.onReady(function(){
          // shorthand
          var Tree = Ext.tree;

          var tree = new Tree.TreePanel({
          el:'tree-div',
          autoScroll:true,
          animate:true,
          enableDD:true,
          containerScroll: true,
          loader: new Tree.TreeLoader({
          dataUrl:'http://localhost:8080/extTest/menus.action'
          })
          });

          // set the root node
          var root = new Tree.AsyncTreeNode({
          text: 'Ext JS',
          href:'http://baidu.com',
          draggable:false,
          id:'source'
          });
          tree.setRootNode(root);

          // render the tree
          tree.render();
          root.expand();
          });

          # re: Extjs Tree + JSON + Struts2 [未登錄]  回復  更多評論   

          2008-02-21 08:41 by 云自無心水自閑
          @xt
          這需要給樹中節點添加點擊的偵聽函數:
          Ext.getCmp("menuTree").on('click', function(node) {
          if ( node.id == 1 ) {
          Ext.get("center-iframe").dom.src = 'http://www.google.com';
          } else {
          node.toggle();
          }
          });


          其中menuTree是TreePanel的id,
          center-iframe是嵌入在另一個面板中的iframe的id

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-02-21 10:57 by xt
          謝謝!我試試看吧.我的msn:xiaoqiu369@hotmail.com,希望有時間多向你請教!

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-03-09 00:56 by topsonstar
          使用json-plugin也可以,只要在TreeLoader的processResponse處理一下,把返回的json對象處理為數組.

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-03-22 21:07 by hua_y9
          謝謝,給予了很好的幫助~ :)

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-03-24 14:10 by laitao
          有沒有struts+ext整合的DEMO,我不知道怎么弄呢,如果有的話,請給我發一份好嗎,郵箱1758_love@163.com

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-04-22 10:32 by ph
          幫我解決了問題啊

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-04-25 09:31 by Nicolas
          內容很棒。多謝

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-05-23 18:18 by gba
          我按照文章的步驟來寫的,但是雖然能夠得到樹,而且該樹的root節點前面有+號,但是我一點那個+號,卻出來不了子結點(并且+號消失),請問lz是怎么回事呢?謝謝了

          我得到的json字符串是[{"children":[{"children":[],"cls":"file","id":11,"leaf":true,"text":"S600"},{"children":[],"cls":"file","id":12,"leaf":true,"text":"SLK200"}],"cls":"folder","id":10,"leaf":false,"text":"Benz"},{"children":[{"children":[],"cls":"file","id":21,"leaf":true,"text":"325i"},{"children":[],"cls":"file","id":22,"leaf":true,"text":"X5"}],"cls":"folder","id":20,"leaf":false,"text":"BMW"}]

          # re: Extjs Tree + JSON + Struts2 [未登錄]  回復  更多評論   

          2008-06-17 13:46 by 堅持到底
          你好,我按照上面的例子做完之后發現這不是一棵異步加載的樹呀!樓主還有沒有異步加載的例子了?

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-06-19 14:06 by usherlight
          @堅持到底
          你說的是lazy load還是async load?

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-07-07 17:24 by cqy
          請問,如何在葉子節點上加入點擊事件呢?

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-07-08 13:29 by usherlight
          @cqy
          這需要給樹中節點添加點擊的偵聽函數:
          Ext.getCmp("menuTree").on('click', function(node) {
          if ( node.id == 1 ) {
          Ext.get("center-iframe").dom.src = 'http://www.google.com';
          } else {
          node.toggle();
          }
          });


          其中menuTree是TreePanel的id,
          center-iframe是嵌入在另一個面板中的iframe的id

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-06 11:07 by cqq
          如何判定本次點擊的node為原有的node呢?
          就是不想重新加載頁面。

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-06 14:30 by cqq
          問題已經解決,分享一下!
          tree.on('beforeclick', function(n)
          alert(n.id);
          var sn = this.selModel.selNode || {};// 取原選定的node
          if( n.id != sn.id){ // ignore clicks on folders and currently selected

          var paramsStr;
          paramsStr="FItemClassID=" + n.id+ "&param2=bar";
          //tree與grid組合時,可以使用以下方法只更新grid
          Ext.get("grid").load({
          url: "tryMc.aspx",
          scripts: true,
          params: paramsStr ,
          text: "正在加載數據,請稍侯……"
          });


          }
          });

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-07 08:56 by usherlight
          @cqq
          謝謝分享

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-12 10:08 by 大帥
          請問。 你的 第五步 menu.jsp 這個是干嘛的呀。 貌似他也不用來顯示東西吧。

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-12 12:11 by 大帥
          按照您做的 ,果然搞定了。。
          偉大。。

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-12 12:16 by 大帥
          問題又出來了啊。。。
          難道使用struts2 后面的只要返回json的 難道都要 多建立一個jsp頁面用于接受 action返回的 字段么?

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-08-12 20:03 by usherlight
          @大帥
          可以都使用menu.jsp

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-09-12 16:49 by solar
          能不能這你這個源碼發一個給我,我照 著做的,就是沒效果,solar_mx@163.com

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-09-18 23:55 by errorfun
          EXT中的JsonStore有個root屬性,是取你返回的對象對應名稱的數據。只要那個名稱對應的是數組就可以了。

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-10-11 10:39 by 安安
          @cqq
          為什么var sn = this.selModel.selNode || {};我取的是現在選中的node的值啊!

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-10-15 15:27 by dgz
          有些包不知道在哪里下,

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-10-21 22:14 by mnzi
          能提供下載嗎?不成功

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-12-21 10:55 by snowwolf
          怎么把數據返回給后臺 ?

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-12-21 14:41 by usherlight
          @snowwolf
          可以參考cqq的答復

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-12-28 15:07 by Iain
          是我漏掉哪一步了么,
          [{"id":7,"leaf":true,"text":"組織管理"},{"id":8,"leaf":true,"text":"用戶管理"},{"id":9,"leaf":true,"text":"角色管理"},{"id":10,"leaf":true,"text":"模塊設置"},{"id":16,"leaf":true,"text":"系統設置"},{"id":17,"leaf":true,"text":"操作日志查詢"},{"id":18,"leaf":true,"text":"通知日志"}]

          和spirng2.5,hib3,struts2,一起從mysql里刷出來的數據. 就想實現點擊父節點是觸發異步刷新. 請指教下, 異常感謝!

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2008-12-28 16:19 by Iain
          @gba

          我也是子節點顯示不出, 控制臺能打出來正常的json串.

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-02-23 23:26 by jache
          能說明一下第五步是干什么用的??

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-03-16 15:00 by l932
          第五步的menu.jsp到底是在哪加載的

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-03-20 10:58 by usherlight
          @l932
          在record.js中的dataUrl是:http://localhost:8080/lab/menus.action
          而在struts.xml中,menu.jsp是menu.action的返回頁面

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-05-25 16:44 by why
          在action那里,最后寫 ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
          PrintWriter out=ServletActionContext.getResponse().getWriter();

          out.print(menuString);

          out.close();
          這樣就可以省掉menu.jsp這一步..

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-05-26 09:15 by usherlight
          @why
          Thanks a lot.

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-08-15 10:53 by xiao huang
          能不能這你這個源碼發一個給我,我照 著做的,就是沒效果,
          hyouz126@126.com

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-08-15 11:04 by xiao huang
          @大帥
          能不能把你源碼發來看看, hyouz126@126.com

          # re: Extjs Tree + JSON + Struts2 [未登錄]  回復  更多評論   

          2009-09-11 10:39 by 小鳥
          非常感謝,按源碼整出來了

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-09-28 11:00 by 張閃閃
          var tree = new Tree.TreePanel({
          el:'tree-div',
          autoScroll:true,
          animate:true,
          enableDD:true,
          containerScroll: true,
          loader: new Tree.TreeLoader({
          dataUrl:'http://localhost:8080/extTest/menus.action'
          })
          });
          葉子節點同樣也會進入“menus.action”,我也要葉子節點進入另外的Action,請問怎么做?

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-09-29 15:49 by mooxin
          能不能給我發一份源碼,mooxin@163.com.cn,先謝謝了!

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2009-12-02 09:14 by 哎,不會利用客戶端資源
          差勁,還要服務端組合成數據格式,這還要你這樣做干什么呢?

          # re: Extjs Tree + JSON + Struts2 [未登錄]  回復  更多評論   

          2009-12-07 17:02 by wolf
          好東西頂了

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2010-05-11 11:35 by
          帥哥我想問下,我按照你的做法,可是報錯了
          net.sf.json.JSONException: There is a cycle in the hierarchy!

          一個死循環。。。。

          這是什么問題呢?可以的話加下我QQ行嗎?378578601

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2010-05-11 11:35 by
          帥哥我想問下,我按照你的做法,可是報錯了
          net.sf.json.JSONException: There is a cycle in the hierarchy!

          一個死循環。。。。

          這是什么問題呢?可以的話加下我QQ行嗎?378578601

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2010-05-11 20:32 by usherlight
          @金
          應該是你的JSON返回串的問題。

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2010-05-11 20:36 by usherlight
          @哎,不會利用客戶端資源
          權限的數據應該存儲在服務器端面吧。

          # re: Extjs Tree + JSON + Struts2 [未登錄]  回復  更多評論   

          2012-05-29 13:24 by K
          如果從數據庫調用數據呢。不是寫死了。要怎么做

          # re: Extjs Tree + JSON + Struts2   回復  更多評論   

          2014-04-12 10:55 by 趙帥帥
          實體類menu中,hebernate注解怎么寫
          主站蜘蛛池模板: 自贡市| 新宁县| 米泉市| 丰台区| 三明市| 治多县| 渝北区| 惠东县| 车致| 麻城市| 赞皇县| 凉城县| 南丰县| 石首市| 丹棱县| 雷山县| 甘泉县| 灵寿县| 万山特区| 阳东县| 台北县| 九寨沟县| 汨罗市| 松溪县| 怀柔区| 舞钢市| 哈密市| 江北区| 澜沧| 旺苍县| 清流县| 兴仁县| 论坛| 崇义县| 腾冲县| 贵南县| 泰州市| 临颍县| 石首市| 鹤峰县| 中山市|