1. 程式人生 > >使用ExtJS2構造動態非同步載入的樹

使用ExtJS2構造動態非同步載入的樹

標題:使用ExtJS2構造動態非同步載入的樹

作者:JRQ   連結:http://blog.csdn.net/jrq/archive/2008/06/15/2549839.aspx   正文:   使用ExtJS2,以JSON(JavaScript Object Notation)TreeLoader 非同步讀取資料,構造一棵非同步載入的樹。     1. 下載ExtJS2,地址:http://www.extjs.com/  
   下載Ext JS 2.1 SDK:ext-2.1.zip。      examples資料夾下全部是ExtJS例子演示程式。      ExtJS2主要的會用到以下幾個檔案:ext-all.css、ext-base.js、ext-all.js,使用方法可以參考Demo。      Ext文件中心:         http://www.ajaxjs.com/docs/docs/
        http://www.jackytsu.com/extcn/docs/       2. 下載JSON-lib,地址:http://json-lib.sourceforge.net/      開啟網址後,首頁上有一段話:         Json-lib requires (at least) the following dependencies in your classpath:
        jakarta commons-lang 2.3       jakarta commons-beanutils 1.7.0       jakarta commons-collections 3.2       jakarta commons-logging 1.1.1       ezmorph 1.0.4      需要下載上述jar檔案,配合JSON-lib 一起使用。       commons 下載地址:http://commons.apache.org/      ezmorph 下載地址:http://ezmorph.sourceforge.net      或者,到 http://www.docjar.com 搜尋下載。      JSON的用法,可參考相關文件。       3. 使用ExtJS寫的mytree.js檔案。      關於Ext.tree.TreePanel,可以參考:      http://www.jackytsu.com/extcn/docs/output/Ext.tree.TreePanel.html        mytree.js程式碼如下:   --------------------------------------    Ext.onReady(function(){      var Tree = Ext.tree;      //定義根節點的Loader    var treeloader=new Tree.TreeLoader({dataUrl:'tree.jsp?DID=1'});       //非同步載入根節點    var rootnode=new Tree.AsyncTreeNode({         id:'1',         text:'目錄樹根節點'                 });         var treepanel = new Tree.TreePanel({                 //renderTo:"tree_div",//如果使用renderTo,則不能使用setRootNode()方法,需要在TreePanel中設定root屬性。                 el:'tree_div',        //填充區域                 rootVisible:true,     //隱藏根節點                 border:true,          //邊框                 animate:true,         //動畫效果                 autoScroll:true,      //自動滾動                 enableDD:false,       //拖拽節點                              containerScroll:true,                 loader:treeloader                         });      //設定根節點    treepanel.setRootNode(rootnode);      //響應事件,傳遞node引數    treepanel.on('beforeload',                 function(node){                    treepanel.loader.dataUrl='tree.jsp?DID='+node.id;    // 定義子節點的Loader                    });      treepanel.render();               rootnode.expand(false,false); });   --------------------------------------     4. 展示樹的extjsTree.jsp的檔案。該jsp檔案呼叫mytree.js,展示樹。      注意使用到了ext-all.css、ext-base.js、ext-all.js這三個檔案。      extjsTree.jsp 程式碼如下:   --------------------------------------   <html> <head> <title>ExtJS Tree</title> <link rel="stylesheet" type="text/css" href="../extjs/ext-all.css" /> <script type="text/javascript" src="../extjs/ext-base.js"></script> <script type="text/javascript" src="../extjs/ext-all.js"></script>   <script type="text/javascript" src="../extjs/mytree.js" defer=true charset="GBK"></script> </head>   <body> <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0" onContextMenu="return false;">  <tr>    <td align=left valign="top" >       <!-- 樹的填充區域-->       <div id="tree_div" style="height:101%;width:100%"></div>    </td>  </tr> </table> </body> </html>   --------------------------------------       5. 構造樹節點。        定義樹節點的屬性,包括節點ID、Text、圖示、是否為葉子節點、是否展開等。      JSONTreeNode.java程式碼如下:   --------------------------------------    package com.tree;   import java.io.Serializable;   public class JSONTreeNode implements Serializable{       private static final long serialVersionUID = 1L;       public static void main(String[] args) {         }          private String id;            //ID      private String text;          // 節點顯示      private String cls;           // 圖示      private boolean leaf;         // 是否葉子      private String href;          // 連結      private String hrefTarget;    // 連結指向      private boolean expandable;   // 是否展開      private String description;   // 描述資訊                //get 、set方法。略。       } }   --------------------------------------        6. 從資料庫查詢,讀取位元組點資料及構造JSON資料。        JSONTree.java程式碼如下:   --------------------------------------  package com.tree;   import java.sql.Connection; import java.sql.Statement; import java.sql.ResultSet; import java.util.ArrayList; import net.sf.json.JSONArray; import com.db.DBConnction; import com.tree.JSONTreeNode;   public class JSONTree{     private String PID;         public String getJSONString(){              Connection conn =null;         Statement st = null;         ResultSet rs = null;         ArrayList<JSONTreeNode> TreeNodeArray = null;                 String SQLString = "SELECT * FROM S_MLS WHERE PID="+this.PID+" ORDER BY DID";                        try         {             conn = DBConnction.getConnection();             st = conn.createStatement();                             rs = st.executeQuery("SELECT PID FROM S_MLS WHERE PID>0 Group By PID Order By PID");                                    StringBuffer parentIDBuffer =new StringBuffer();             parentIDBuffer.append("|");                     while(rs.next())             {                 parentIDBuffer.append(rs.getString("PID"));                 parentIDBuffer.append("|");             }             // 得到所有的parentDID列表(這是一個巧妙的演算法^_^)             String parentIDString = parentIDBuffer.toString();                                 rs = st.executeQuery(SQLString);                TreeNodeArray = new ArrayList<JSONTreeNode>();                          while(rs.next())             {                 JSONTreeNode TreeNode = new JSONTreeNode();                 TreeNode.setId(rs.getString("DID"));                 TreeNode.setText(rs.getString("JDMC"));                 TreeNode.setDescription(rs.getString("JDMC"));                              TreeNode.setHref("rightframe.jsp?did="+rs.getString("DID").toString());                     TreeNode.setHrefTarget("rightFrame");                                               if (parentIDString.indexOf("|"+rs.getString("DID")+"|")>=0) // 父節點                     {                         TreeNode.setCls("folder");                         TreeNode.setLeaf(false);                         TreeNode.setExpandable(false);                     }                     else // 子節點                    {                         TreeNode.setCls("file");                         TreeNode.setLeaf(true);                         TreeNode.setExpandable(false);                     }                     TreeNodeArray.add(TreeNode);             }                         JSONArray JsonArray = JSONArray.fromObject(TreeNodeArray); // 得到JSON陣列                   return JsonArray.toString();// 返回JSON資料         }         catch(Exception e)         {             System.out.println("getJSONString() of JSONTree.java throws : "+e.toString());             return "";         }         finally         {             DBConnction.closeConnection(conn,st,rs);         }     }           public String getPID() {         return PID;     }       public void setPID(String pid) {         PID = pid;     } }   --------------------------------------      7. mytree.js中ExtJS的TreeLoader呼叫的tree.jsp。      在目錄樹上點選TreeNode後會載入下一級節點。       tree.jsp負責TreeNode點選後,傳回由下一級節點構造的JSON資料。      tree.jsp程式碼如下:   --------------------------------------    <%@ page language="java" pageEncoding="GBK"%>   <jsp:useBean class="com.thams.tree.JSONTree" id="JSONTree"></jsp:useBean>   <%   String PID = "";    if (request.getParameter("DID")!=null)  {     PID = request.getParameter("DID").toString();  }    JSONTree.setPID(PID); %>   <%=JSONTree.getJSONString()%>   --------------------------------------      7. 江湖故事        1). 如果要做ExtJS Tree的DEMO,生成TreeLoader()時,儘量不要使用靜態的JSON格式檔案。               如            Tree.TreeLoader({dataUrl:'/jsondata.txt'});              Tree.TreeLoader({dataUrl:'/jsondata.js'});            等諸如此類。            在網上查資料時,做ExtJS Tree時,很多資料說使用靜態的JSON檔案做Demo,我使用ExtJS2.1,一次沒有成功。          為此浪費了很多時間精力,付出慘重代價。        2). 使用JSON的時候,需要一些jar檔案來配合使用。          從網上下載的時候,很多是zip檔案,當時沒有多加考慮,按照以往的經驗,直接修改後綴名為jar,然後匯入到lib資料夾,結果會報錯。          諸如:          javax.servlet.ServletException: org/apache/commons/lang/exception/NestableRuntimeException          java.lang.NoClassDefFoundError: org/apache/commons/lang/exception/NestableRuntimeException            查了很多資料,沒有搞定。          開始以為是jar版本不匹配造成的。在這個問題上折騰了很久,亦浪費很多時間和精力,痛苦啊。          精神的折磨。          其實,真正的jar檔案需要解壓zip檔案後才能得到的。低階錯誤。崩潰。        3). 關於s.gif檔案的問題               該問題會在系統不連網際網路的情況下暴露。               因為ExtJS在生成Tree時,預設情況下,總是訪問http://extjs.com/s.gif下載這個s.gif圖片檔案。          在不連網的情況下,樹節點的導航圖片顯示不出,通過右鍵屬性可知,是http://extjs.com/s.gif。          通過搜尋,發現該s.gif是在ext-base.js這個檔案中定義的:             BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif"          並且ExtJS中的示例程式是帶有這個s.gif圖片檔案的。                根據具體應用情況,把ext-base.js修改成為:          BLANK_IMAGE_URL:"../images/default/s.gif"        4). 除錯的時候,JS報錯:未結束的字串常量。         這個問題是因為JS呼叫時沒有指定字符集,造成JS裡的漢字出現亂碼引起的。         呼叫JS時,可以指定使用字符集。         如 <script type="text/javascript" defer=true src="xxx.js" charset="GBK">     8. AJAX      AJAX Asynchronous JavaScript and XML(非同步JavaScript和XML)          只是為了樹,也要學ExtJS。      ExtJS2.1+JSON = 動態非同步載入的樹       [--完--]                                                                           By JRQ                                                                        2008/06/15 於京 ========================================================= ========================================================= ========================================================= 【轉載注】    配置須知:   1、資料庫對應的表中必須新增一個虛根!該虛根是一級節點的父節點。   2、最好把Ext的相關檔案都放到專案中——不僅僅是文章1中說的ext-all.css、ext-base.js、ext-all.js這三個檔案。   3、如果使用的JDK是1.5之前的版本,那麼必須下載一個json-lib-2.2.2-jdk13.jar。   4、必須注意文章2中說的jar包的版本!