使用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 = 動態非同步載入的樹
原文地址:http://caodaoxi.javaeye.com/blog/787910