使用xloadtree讀取數(shù)據(jù)庫動態(tài)構(gòu)造樹
原先系統(tǒng)使用xtree讀取數(shù)據(jù)庫構(gòu)造的樹,是jsp一次性生成所有的節(jié)點(diǎn)的,因?yàn)閿?shù)據(jù)量也不大,所以用用還挺好。今天特來興致,決定改造。當(dāng)點(diǎn)擊父節(jié)點(diǎn)的時(shí)候,才去數(shù)據(jù)庫動態(tài)的獲取子節(jié)點(diǎn),這樣對于大數(shù)據(jù)量的系統(tǒng),性能比較好。
首先下載 http://webfx.eae.net/dhtml/xtree2b/xtree2b-20050606.zip
這包里面有簡單的示例,廢話少說,動手
- <link type="text/css" rel="stylesheet" href="<%=request.getContextPath() %>/css/xtree2.css">
- <link type="text/css" rel="stylesheet" href="<%=request.getContextPath() %>/css/xtree2.links.css">
- <script type="text/javascript" src="<%=request.getContextPath() %>/script/xtree2.js"></script>
- <script type="text/javascript" src="<%=request.getContextPath() %>/script/xloadtree2.js"></script>
首先構(gòu)造樹的jsp文件要加載相關(guān)js和css文件,上面down的zip里面都有,放到你的項(xiàng)目里面
jsp端加入腳本,構(gòu)造樹
- <div style="left:20px;top:30px;width:100%;">
- <script>
- var tree = new WebFXTree('root node');
- tree.add(new WebFXLoadTreeItem("all node", "/cmsCatalogQueryAction.do?method=tree","javascript:modifyNode('cmsCatalogMaintAction.do?method=new')"));
- tree.showRootNode = false;
- tree.showRootLines = false;
- tree.write();
- </script>
/cmsCatalogQueryAction.do?method=tree是生成相關(guān)xml的action地址
javascript:modifyNode('cmsCatalogMaintAction.do?method=new')這個(gè)是點(diǎn)擊根節(jié)點(diǎn)的時(shí)候action的地址,比如鏈接到添加一級節(jié)點(diǎn)的頁面,(modifyNode是我項(xiàng)目里面用的js函數(shù),目的是在右邊的frame里面打開后面的參數(shù)地址)
tree.showRootNode = false;
tree.showRootLines = false;
為了把a(bǔ)ll node作為根節(jié)點(diǎn),所以隱藏root node節(jié)點(diǎn)
下面看看action端的寫法
- public ActionForward tree(
- ActionMapping actionMapping,
- ActionForm actionForm,
- HttpServletRequest request,
- HttpServletResponse response)
- throws Exception {
- response.setContentType("text/xml; charset=gbk");
- response.setHeader("Cache-Control", "no-cache");
- response.setDateHeader("Expires", 0);
- PrintWriter out = response.getWriter();
- String id = request.getParameter("id");
- Document doc = new Document(new Element("tree"));
- if (StringUtils.isEmpty(id)) {
- List list = getCmsFacade().getRootCatalogListByDomainID(HConstant.currentDomain.getId());
- transfer(doc, list);
- } else {
- List list = getCmsFacade().getCmsCatalogListByParentID(id);
- transfer(doc, list);
- }
- Format format = Format.getCompactFormat();
- format.setEncoding("gbk");
- format.setIndent("/t");
- XMLOutputter xout = new XMLOutputter(format);
- xout.output(doc, out);
- out.flush();
- out.close();
- return null;
- } // end tree
- private void transfer(Document doc, List r) {
- for (Iterator it = r.iterator(); it.hasNext();) {
- CmsCatalog one = (CmsCatalog) it.next();
- Element tree = doc.getRootElement();
- Element inner = new Element("tree").setAttribute("text", one.getZhCaption());
- tree.addContent(inner);
- inner.setAttribute("src", "/cmsCatalogQueryAction.do?method=tree&id="+ one.getId());
- inner.setAttribute("action", "javascript:refun('"+one.getId()+"','"+one.getZhCaption()+"')");
- }
- }
這邊的代碼要根據(jù)你的業(yè)務(wù)來寫了,我的欄目對象叫CmsCatalog。生成xml使用了jdom,代碼中的Document 和Element這些class都是這個(gè)包里面的
getCmsFacade().getRootCatalogListByDomainID是獲取本站點(diǎn)的所有一級欄目,
getCmsFacade().getCmsCatalogListByParentID是根據(jù)父ID得到下一級欄目列表,(不是得到所有的子,只獲取直接下級的子)
獲取到欄目list后,要轉(zhuǎn)換成對應(yīng)xml規(guī)范,參看transfer方法,轉(zhuǎn)后的數(shù)據(jù)格式如下,以根節(jié)點(diǎn)為例
- <?xml version="1.0" encoding="gbk" ?>
- - <tree>
- <tree text="關(guān)于我們" src="/cmsCatalogQueryAction.do?method=tree&id=4028e44919c7e5290119c7e754330001" action="javascript:refun('4028e44919c7e5290119c7e754330001','關(guān)于我們')" />
- <tree text="新聞頻道" src="/cmsCatalogQueryAction.do?method=tree&id=4028e4491a04a4fb011a04ab42ae005e" action="javascript:refun('4028e4491a04a4fb011a04ab42ae005e','新聞頻道')" />
- <tree text="產(chǎn)品與解決方案" src="/cmsCatalogQueryAction.do?method=tree&id=4028e4491a80ec5b011a811c1b570002" action="javascript:refun('4028e4491a80ec5b011a811c1b570002','產(chǎn)品與解決方案')" />
- <tree text="服務(wù)與支持" src="/cmsCatalogQueryAction.do?method=tree&id=4028e4491a900271011a9042bb810003" action="javascript:refun('4028e4491a900271011a9042bb810003','服務(wù)與支持')" />
- <tree text="英才導(dǎo)航" src="/cmsCatalogQueryAction.do?method=tree&id=4028e4491a33c105011a33d2f5b90002" action="javascript:refun('4028e4491a33c105011a33d2f5b90002','英才導(dǎo)航')" />
- <tree text="聯(lián)系我們" src="/cmsCatalogQueryAction.do?method=tree&id=4028e4491a805657011a80d2cae90006" action="javascript:refun('4028e4491a805657011a80d2cae90006','聯(lián)系我們')" />
- </tree>
當(dāng)點(diǎn)擊一個(gè)節(jié)點(diǎn)的時(shí)候,會執(zhí)行refun這個(gè)js函數(shù),為什么不直接寫一個(gè)鏈接呢? 因?yàn)橐粋€(gè)欄目樹可能在很多地方都要用到,點(diǎn)擊樹的鏈接也因此可能不一樣了,所以不能在action寫死具體地址。構(gòu)造樹的jsp頁面直接寫一個(gè)refun函數(shù)就ok了,自己去定義點(diǎn)擊節(jié)點(diǎn)時(shí)候的操作。服務(wù)端返回了兩個(gè)欄目參數(shù)給refun函數(shù),一個(gè)是id,一個(gè)中文名稱
當(dāng)點(diǎn)擊最后一級節(jié)點(diǎn)的時(shí)候,會提示加載節(jié)點(diǎn)錯(cuò)誤的信息,這個(gè)是xloadtree的一個(gè)bug,我們手動修改下就ok了,編輯xloadtree2.js文件,找到
if (count == 0) {
jsNode.errorText = "Error loading " + jsNode.src + " (???)";
}
修改為
if (count == 0) {
jsNode.remove(jsNode._loadingItem);
t.setSuspendRedraw(false);
jsNode.update();
return;
}
當(dāng)返回的xml 為空的時(shí)候,把節(jié)點(diǎn)設(shè)置為無子節(jié)點(diǎn)
到此,動態(tài)加載樹就完成了,相當(dāng)簡單吧,你唯一要做的就是合理的把你的欄目列表從數(shù)據(jù)庫取出來,然后正確的填充到xml里面,就ok了