2012/11/20javascript
發現項目中用到一個TreeCheckNodeUI插件,直接添加checked屬性並不能實現級聯選擇,不少關於選擇的部分還要本身實現,這個插件幫助完成了這些事情。php
貌似是插件出處?css
相關:EXT2.0 checkbox樹的擴展(級聯)_測試及解決方案html
雖然不錯,仍是存在Bug,並且沒有半選狀態,而後發現了還有三態的版本java
這個不錯,在上面稍微作了點修改就用上了,可是代碼沒有全理解... 能夠像使用上面那個插件那樣使用,不用把TreeLoader
改爲他定義的TreeCheckLoader
數組
其它:app
雖然走了點彎路,可是理解了DwrTreeLoader是怎麼使用的。
========== 華麗的分割線 ==========
需求:在項目中使用了DwrTreeLoader來做爲ExtJS的TreeLoader,有的樹控件須要顯示CheckBox,而有的不須要顯示,經過傳入參數來控制是否顯示CheckBox
參考:ExtJs結合Dwr的tree,沒有介紹如何傳參數,做爲入門Demo
要使TreeNode帶複選框,只要加上checked
屬性便可,可參考Ext結合Dwr帶複選框的樹,基本的代碼和上面那篇文章沒啥區別
網上有一篇寫ExtJS中DWRTreeLoader的兩個版本的差異, 其實沒啥區別,只是DWRTreeLoader.js源代碼中一個屬性的名稱改了一下
由於對上面Demo的改動比較大,並且網上也沒有解釋得比較清楚的文章,故寫這篇文章做爲記錄
Demo結構:
首先,配置Extjs,按目錄結構裏面的拷貝幾個文件就好了,這裏用的是3.x的版本(由於目前作的項目用的這個版本,測試了下4.x的版本沒有成功,不知道問題在哪)
接着,要配置Dwr,直接把以前寫的DwrDemo的幾個文件拷貝過來就搞定了,這裏不重複說明
dwr.xml
<!-- lang: xml --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd"> <dwr> <allow> <create creator="new" javascript="TreeService"> <param name="class" value="zoey.extjs.dwr.tree.TreeService" /> </create> <convert converter="bean" match="zoey.extjs.dwr.tree.Node" /> </allow> </dwr>
Node.java修改成使用Map<String, Object>
來保存結點屬性,能夠更靈活
<!-- lang: java --> package zoey.extjs.dwr.tree; import java.util.HashMap; import java.util.Map; public class Node { private Map<String, Object> nodeMap; public Node(int id, String text, boolean leaf, boolean checkBox) { nodeMap = new HashMap<String, Object>(); nodeMap.put("id", id); nodeMap.put("text", text); nodeMap.put("leaf", leaf); // 經過傳入的參數checkBox是否爲true,來控制是否顯示覆選框 if (checkBox) { nodeMap.put("checked", false); } } public Map<String, Object> getNodeMap() { return nodeMap; } public void setNodeMap(Map<String, Object> nodeMap) { this.nodeMap = nodeMap; } }
TreeService.java
<!-- lang: java --> package zoey.extjs.dwr.tree; import java.util.ArrayList; import java.util.List; import java.util.Map; public class TreeService { public List<Map<String, Object>> getAllChildren(String parentId, boolean checkBox) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); if (parentId.equals("root")) { list.add(new Node(1, "子節點1", false, checkBox).getNodeMap()); list.add(new Node(2, "子節點2", false, checkBox).getNodeMap()); list.add(new Node(3, "子節點3", false, checkBox).getNodeMap()); list.add(new Node(4, "子節點4", false, checkBox).getNodeMap()); list.add(new Node(5, "子節點5", false, checkBox).getNodeMap()); list.add(new Node(6, "子節點6", false, checkBox).getNodeMap()); } else if (parentId.equals("2")) { list.add(new Node(7, "孫子節點7", true, checkBox).getNodeMap()); list.add(new Node(8, "孫子節點8", true, checkBox).getNodeMap()); list.add(new Node(9, "孫子節點9", true, checkBox).getNodeMap()); } else if (parentId.equals("4")) { list.add(new Node(11, "孫子節點11", true, checkBox).getNodeMap()); list.add(new Node(12, "孫子節點12", true, checkBox).getNodeMap()); list.add(new Node(13, "孫子節點13", true, checkBox).getNodeMap()); } else if (parentId.equals("6")) { list.add(new Node(21, "孫子節點21", true, checkBox).getNodeMap()); list.add(new Node(22, "孫子節點22", true, checkBox).getNodeMap()); list.add(new Node(23, "孫子節點23", true, checkBox).getNodeMap()); } return list; } }
tree.js
<!-- lang: js --> Ext.onReady(function() { var root = new Ext.tree.AsyncTreeNode({ id: "root", leaf: false, text: "樹的根", checked: false // ===== 控制根結點顯示CheckBox ===== }); var treeloader = new Ext.ux.DWRTreeLoader({ // 構造器調用模式 // ===== 屬性名爲dwrCall,由於DWRTreeLoader.js中調用了這個屬性, // (搜"this.dwrCall"可搜到,舊的名稱爲dwrMethod或dataURL, // 關鍵看DWRTreeLoader中怎麼命名的) ===== dwrCall: TreeService.getAllChildren, // ===== 傳入參數,DWRTreeLoader中可以使用this.params進行調用,名字可有可無,也能夠不寫成這種形式 // 關鍵是知道在DWRTreeLoader中可使用this調用這裏的屬性 ===== params: { checkBox: true } }); var viewTree = new Ext.tree.TreePanel({ id: "vtree", renderTo: "tree", root: root, loader: treeloader, width: 200, height: 300, title: "動態遍歷樹", useArrows: true, //是否使用箭頭樣式 autoScroll: true, //滾動條 animate: true, //展開,收縮動畫 rootVisible: true, //根節點是否可見 // enableDD: true, //是否能夠拖放節點 tools: [{ id: 'refresh', handler: function () { var tree = Ext.getCmp('vtree'); tree.body.mask("數據加載中..", "x-mask-loading"); tree.root.reload(); tree.root.expand(true, false, function() { tree.body.unmask(); }); } }], region: "west", collapseMode: "mini", collapsible: true, //面板是可收縮的,並自動渲染一個展開/收縮的輪換按鈕在頭部工具條 split: true, border: false }); });
DWRTreeLoader.js
可在這裏找到最原始的代碼:DwrTreeLoader source
這裏稍微作了修改(只給出修改的部分):
<!-- lang: js --> /** * Override this to add custom request parameters. Default adds the node id as first and only parameter */ getParams : function (node) { var callParams = []; callParams.push(node.id); for (var key in this.params) { callParams.push(this.params[key]); } return callParams; },
上面的this.params
就是new Ext.ux.DWRTreeLoader({})
中傳入的屬性
在requestData
函數中有callParams
數組,採用了apply調用模式,this.dwrCall.apply(this, callParams);
,callParams數組做爲參數傳入TreeService.getAllChildren
函數,須要注意傳入參數的順序。
index.jsp
<!-- lang: html --> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path; %> <!DOCTYPE html> <html> <head> <base href="<%=basePath%>"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Hello ExtJS DWR Tree</title> <link rel="stylesheet" type="text/css" href="<%=basePath%>/extjs/resources/css/ext-all.css" /> <script type="text/javascript" src="<%=basePath%>/extjs/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="<%=basePath%>/extjs/ext-all.js"></script> <script type="text/javascript" src="<%=basePath%>/js/tree.js"></script> <script type='text/javascript' src='<%=basePath%>/js/DWRTreeLoader.js'></script> <script type='text/javascript' src='<%=basePath%>/dwr/engine.js'></script> <script type='text/javascript' src='<%=basePath%>/dwr/interface/TreeService.js'></script> <script type='text/javascript' src='<%=basePath%>/dwr/util.js'></script> </head> <body><div id="tree"></div></body> </html>
這裏就能夠經過設置params: { checkBox: true }
的checkBox
值爲true
或false
來控制是否顯示覆選框了
也能夠傳入其它的參數,在後臺作更多的擴展
注:對代碼的解釋部分,水平有限按本身的想法說明,發現不對的會即時改正。