zTree外掛在struts2中構建樹狀分支結構
在常見的管理系統中,一般會用到樹狀分支結構——把某些屬於同一範疇的功能放在同一個“樹枝”上,“樹枝”上有一些不同的功能節點,點選功能節點則會彈出相應的處理頁面。而這些節點通常不是寫死的,而是從資料庫中讀取出來的。下面就如何在struts2中利用zTree外掛,來實現這種結構做一個小結。
首先,實現效果如下:
1.資料庫中對應建立一個t_node的表,包含一些id, parent_id, name, url, tree_str, item_id等等一些關鍵欄位。其中parent_id = 0表明為父節點;父節點的id對應隸屬於它的子節點的parent_id。在這張表中填入節點資訊。
2.開始在struts.xml中配置json傳遞的相關資訊
<result-types> <result-type name="json" class="com.googlecode.jsonplugin.JSONResult" /> </result-types>
當然,點選載入樹狀結構的action和jsp跳轉的配置也不能少:
<action name="Test" class="com.xxx.action.TestAction" method="do{1}"> <result name="tree" type="json"></result> <result name="cat_show">/pages/test/tree_show.jsp</result> </action>
3.對應的tree_show.jsp頁面是用於載入樹狀結構的:
<body style= "margin-left: 3px;margin-top: 0px;margin-right: 3px;margin-bottom: 0px;"> <div style="float: left; width: 22%;"> <TABLE height=600px style=" width:100%; BORDER-RIGHT: #999999 1px dashed" align=left> <TR> <TD width=230px align=left valign=top> <div class="zTreeDemoBackground left"> <ul id="tree" class="ztree" style="width: 200px; overflow: auto;"></ul> </div> </TD> </TR> </TABLE> </div> </body>
這個頁面想要正常顯示zTree,一些很有必要的css和js的引入是關鍵:
<link href="<%=request.getContextPath()%>/css/kkfun.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="<%=basePath%>css/zTreeStyle/zTreeStyle.css">
<script type="text/javascript" src="<%=basePath%>js/jquery-1.4.4.min.js" ></script>
<script type="text/javascript" src="<%=basePath%>js/jquery.ztree.core-3.5.min.js" ></script>
4.tree_show.jsp頁面里加載樹狀結構的關鍵js程式碼:
<script type="text/javascript"> var setting = { view: { dblClickExpand: false, showLine: true, selectedMulti: false }, data: { simpleData: { enable:true, idKey: "id", pIdKey: "parentId", rootPId: "-1" } } }; $(document).ready(function() { $.ajax({ url: "Test!getAllEntry.action", type: "post", dataType: "json", success:initZtree }); }); function initZtree(json) { var nodes = eval(json.jsonString); //alert("樹:" + nodes); var ZtreeObj = $.fn.zTree.init($('#tree'),setting,nodes); } </script>
注意:先是使用者點選相應連結,跳入到jsp頁面。jsp頁面裡$(document).ready(function() 表示在onload該頁面時會執行的程式碼,可以看出是通過一個ajax的方式去呼叫後臺的action來查詢資料庫資料動態構建出節點內容的,執行完畢後,返回一個json給頁面,再通過ajax的success部分把節點內容顯示給id為tree的ul。由此得到根據後臺查詢得出的樹狀節點內容。而不是寫死。
5.後臺處理部分:
step1, 建立一個EntryVO儲存節點物件資訊(包含欄位id, parentId, name, open, url, isParent等);
step2, 進入tree_show.jsp頁面和生成節點資訊的action:
public String doGetAllEntry() {
if(flag !=null && "jump".equals(flag)) {
return "cat_show";
}
List<EntryVO> nodes = null;
try {
entryList = testService.getAllEntry();
if(entryList.size() > 0) {
nodes = new ArrayList<EntryVO>();
EntryVO root = new EntryVO();
root.setId(0L);
root.setparentId(0L);
root.setName("根節點");
root.setIsParent("true");
root.setOpen("true");
root.setTarget("mainFrame");
root.setUrl("Test!GetAllEntry.action?entryVO.id=0&entryVO.parentId=0&entryVO.name=根節點&flag=jump");
nodes.add(root);
//得到所有的parent_id
List<Long> pIds = testService.getAllParentId();
for(EntryVO entry: entryList) {
EntryVO node = new EntryVO();
node.setId(entry.getId());
node.setparentId(entry.getparentId());
node.setName(entry.getName());
node.setOpen("true");
node.setTarget("mainFrame");
//如果某一節點的id被包含在父節點id中,說明它是父節點
if(pIds.contains(entry.getId())) {
node.setIsParent("true");
}
node.setUrl("Test!GetAllEntry.action?entryVO.id=" + entry.getId() +
"&entryVO.parentId=" + entry.getparentId() +
"&entryVO.name=" + entry.getName() + "&flag=jump");
nodes.add(node);
}
}
} catch (Exception e) {
e.printStackTrace();
}
//將查詢結果轉換為json傳入頁面生成樹狀結構
JSONArray jsonArr = JSONArray.fromObject(nodes);
this.jsonString = jsonArr.toString();
System.out.println("樹結構:" + jsonString);
return "tree";
}
(注:相應的查詢方法省略……)
6.特別注意:
1)action中的jsonString要與jsp中eval(json.jsonString)的jsonString命名一致,否則會獲取不到後臺傳遞過來的json字串;
2)特別注意要引入必要的css和js(當然jar包也必須要有);
3)struts.xml中要有<result name="tree" type="json"></result>的配置,對應action中的return "tree";
4)ajax的用法,載入樹狀結構的流程,以及關鍵屬性jump;
7.遇到的問題解決:
問題一:出現異常:
java.lang.AbstractMethodError: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.getClientInfo()Ljava/util/Properties;
解決辦法:action中的呼叫介面xxxService不能有getter方法,去掉即可!
問題二:樹狀結構的父節點無法摺疊和展開:
解決辦法:檢查
data: {
simpleData: {
enable:true,
idKey: "id",
pIdKey: "pId",
rootPId: "-1"
}
}
發現,pIdKey對應的值pId沒有與vo中的parentId命名一致,改成parentId,問題解決!