二話不說,先來看效果圖:javascript
呃呃,雖然不是很美觀......不過功能實現就好啦~css
數據庫模型是這樣的:html
我作了什麼工做呢?前端
簡單解釋一下,就是經過查數據庫,把上面的數據查出來,每一行數據封裝成爲一個節點,而後拼成一顆樹,最後顯示在前臺。注意:這裏的數據是能夠動態擴展的。java
字段解釋:nodeId就是節點的id。pid是 parentId也就是父親的id,表示該節點是哪一個節點的子節點。type=1表明功能,type=0表明菜單。level表明該節點在樹的第幾層。
node
OK,你們應該火燒眉毛想要知道具體實現了.....jquery
知足你們,先來看前端代碼:ajax
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 3 <html> 4 <head> 5 <% 6 String server_path = request.getContextPath(); 7 %> 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 9 </head> 10 <!-- bootstrap-treeview 導包--> 11 <link rel="stylesheet" type="text/css" href="<%=server_path %>/bootstrap-3.3.7-dist/css/bootstrap.css" > 12 <link rel="stylesheet" type="text/css" href="<%=server_path %>/bootstrap-3.3.7-dist/treeview/bootstrap-treeview.css"> 13 <script type="text/javascript" src="<%=server_path %>/bootstrap-3.3.7-dist/treeview/jquery.js"></script> 14 <script type="text/javascript" src="<%=server_path %>/bootstrap-3.3.7-dist/treeview/bootstrap-treeview.js"></script> 15 16 <script type="text/javascript"> 17 //選中/取消父節點時選中/取消全部子節點 18 function getChildNodeIdArr(node) { 19 var ts = []; 20 if (node.nodes) { 21 for (x in node.nodes) { 22 ts.push(node.nodes[x].nodeId); 23 if (node.nodes[x].nodes) { 24 var getNodeDieDai = getChildNodeIdArr(node.nodes[x]); 25 for (j in getNodeDieDai) { 26 ts.push(getNodeDieDai[j]); 27 } 28 } 29 } 30 } else { 31 ts.push(node.nodeId); 32 } 33 return ts; 34 } 35 //選中全部子節點時選中父節點 36 function setParentNodeCheck(node) { 37 var parentNode = $("#tree").treeview("getNode", node.parentId); 38 if (parentNode.nodes) { 39 var checkedCount = 0; 40 for (x in parentNode.nodes) { 41 if (parentNode.nodes[x].state.checked) { 42 checkedCount ++; 43 } else { 44 break; 45 } 46 } 47 if (checkedCount === parentNode.nodes.length) { 48 $("#tree").treeview("checkNode", parentNode.nodeId); 49 setParentNodeCheck(parentNode); 50 } 51 } 52 } 53 54 $(function () { 55 $.ajax({ 56 type: "Post", 57 url: '<%= server_path%>/resource/menu', 58 dataType: "json", 59 success: function (result) { 60 $('#tree').treeview({ 61 data: result.list, // 數據源 62 showCheckbox: true, //是否顯示覆選框 63 highlightSelected: true, //是否高亮選中 64 multiSelect: true, //多選 65 levels : 2, 66 enableLinks : true,//必須在節點屬性給出href屬性 67 color: "#010A0E", 68 onNodeChecked : function (event,node) { 69 var selectNodes = getChildNodeIdArr(node); //獲取全部子節點 70 if (selectNodes) { //子節點不爲空,則選中全部子節點 71 $('#tree').treeview('checkNode', [selectNodes, { silent: true }]); 72 } 73 }, 74 onNodeUnchecked : function(event, node) { //取消選中節點 75 var selectNodes = getChildNodeIdArr(node); //獲取全部子節點 76 if (selectNodes) { //子節點不爲空,則取消選中全部子節點 77 $('#tree').treeview('uncheckNode', [selectNodes, { silent: true }]); 78 } 79 }, 80 81 onNodeExpanded : function(event, data) { 82 83 }, 84 85 onNodeSelected: function (event, data) { 86 //alert(data.nodeId); 87 } 88 89 }); 90 }, 91 error: function () { 92 alert("菜單加載失敗!") 93 } 94 }); 95 }) 96 </script> 97 </head> 98 <body> 99 <div id="tree" class="col-sm-2"></div> 100 </body> 101 </html>
你沒有看錯,就是這麼一個文件就搞定啦。。。spring
對了,導包不要導錯了。沒有這些包能夠去瀏覽器下載bootstrap treeview包。下不來可來找我要。數據庫
okok,而後看神奇的後臺代碼:
1 @Controller 2 @RequestMapping("/resource") 3 public class ResourceController extends BaseController{ 4 5 @RequestMapping("menu") 6 public void getMenu(HttpServletRequest request,HttpServletResponse response) throws Exception{ 7 json.setResult("no"); 8 Node tree = getTreeJson();//得到一棵樹模型的數據 9 //json.setData(tree); 10 json.setList(tree.getNodes()); 11 json.setResult("ok"); 12 response.getWriter().println(mapper.writeValueAsString(json));//把json數據寫回前臺 13 } 14 15 16 public Node getTreeJson() { 17 List<Resource> reslist = resourceService.loadAll();//從數據庫獲取全部資源 18 List<Node> nodes = new ArrayList<Node>();//把全部資源轉換成樹模型的節點集合,此容器用於保存全部節點 19 for(Resource res : reslist){ 20 Node node = new Node(); 21 node.setHref(res.getUrl()); 22 node.setIcon(res.getIcon()); 23 node.setNodeId(res.getNodeId()); 24 node.setPid(res.getPid()); 25 node.setText(res.getName()); 26 nodes.add(node);//添加到節點容器 27 } 28 Node tree = new Node();//重要插件,建立一個樹模型 29 Node mt = tree.createTree(nodes);//Node類裏面包含了一個建立樹的方法。這個方法就是經過節點的信息(nodes)來構建一顆多叉樹manytree->mt。 30 //System.out.println(tree.iteratorTree(mt)); 31 return mt; 32 } 33 34 }
以上代碼,就是負責把數據庫的數據取出來,封裝成對應的節點,根據節點建立一顆樹,而後封裝成json數據傳到前臺,就那麼簡單。
看不懂沒關係,上面用了springmvc框架作控制器,若是你沒有這環境,又想作測試,你徹底能夠用其餘控制器,servlet都行,只要能把json數據傳回前臺就行。固然,上面還用了一些組件,這也沒關係,最重要的不就是紅色部分的代碼嘛,請睜大眼睛:
1 import java.util.ArrayList; 2 import java.util.List; 3 /** 4 * 樹形節點模型 5 * @author chenht 6 * 7 */ 8 public class Node { 9 public Node() { 10 this.nodes = new ArrayList<Node>(); 11 } 12 public Node(String nodeId,String pId) { 13 this.nodeId = nodeId; 14 this.pid = pId; 15 this.nodes = new ArrayList<Node>(); 16 } 17 /** 18 * 生成一個節點 19 * @param nodeId 20 * @param pId 21 * @param text 22 * @param icon 23 * @param href 24 */ 25 public Node(String nodeId, String pId, String text, String icon, String href) { 26 super(); 27 this.nodeId = nodeId; 28 this.pid = pId; 29 this.text = text; 30 this.icon = icon; 31 this.href = href; 32 this.nodes = new ArrayList<Node>(); 33 } 34 35 private String nodeId; //樹的節點Id,區別於數據庫中保存的數據Id。 36 private String pid; 37 private String text; //節點名稱 38 private String icon; 39 private String href; //點擊節點觸發的連接 40 private List<Node> nodes; //子節點,能夠用遞歸的方法讀取 41 42 public String getNodeId() { 43 return nodeId; 44 } 45 public void setNodeId(String nodeId) { 46 this.nodeId = nodeId; 47 } 48 49 public String getPid() { 50 return pid; 51 } 52 public void setPid(String pid) { 53 this.pid = pid; 54 } 55 56 public String getText() { 57 return text; 58 } 59 public void setText(String text) { 60 this.text = text; 61 } 62 63 public String getIcon() { 64 return icon; 65 } 66 public void setIcon(String icon) { 67 this.icon = icon; 68 } 69 70 public String getHref() { 71 return href; 72 } 73 public void setHref(String href) { 74 this.href = href; 75 } 76 77 public List<Node> getNodes() { 78 return nodes; 79 } 80 public void setNodes(List<Node> nodes) { 81 this.nodes = nodes; 82 } 83 84 /** 85 * 生成一顆多叉樹,根節點爲root 86 * @param Nodes 生成多叉樹的節點集合 87 * @return root 88 */ 89 public Node createTree(List<Node> Nodes) { 90 if (Nodes == null || Nodes.size() < 0) 91 return null; 92 Node root = new Node("root","0");//根節點自定義,可是要和pid對應好 93 // 將全部節點添加到多叉樹中 94 for (Node node : Nodes) { 95 if (node.getPid().equals("0") || node.getPid().equals("root")) {//根節點自定義,可是要和pid對應好 96 // 向根添加一個節點 97 root.getNodes().add(node); 98 } else { 99 addChild(root, node); 100 } 101 } 102 return root; 103 } 104 105 /** 106 * 向指定多叉樹節點添加子節點 107 * @param Node 多叉樹節點 108 * @param child 節點 109 */ 110 public void addChild(Node Node, Node child) { 111 for (Node item : Node.getNodes()) { 112 if (item.getNodeId().equals(child.getPid())) { 113 // 找到對應的父親 114 item.getNodes().add(child); 115 break; 116 } else { 117 if (item.getNodes() != null && item.getNodes().size() > 0) { 118 addChild(item, child); 119 } 120 } 121 } 122 } 123 124 /** 125 * 遍歷多叉樹 126 * @param Node 多叉樹節點 127 * @return 128 */ 129 public String iteratorTree(Node Node) { 130 StringBuilder buffer = new StringBuilder(); 131 buffer.append("\n"); 132 if (Node != null) { 133 for (Node index : Node.getNodes()) { 134 buffer.append(index.getNodeId() + ","); 135 if (index.getNodes() != null && index.getNodes().size() > 0) { 136 buffer.append(iteratorTree(index)); 137 } 138 } 139 } 140 buffer.append("\n"); 141 return buffer.toString(); 142 } 143 144 public static void main(String[] args) { 145 List<Node> nodes = new ArrayList<Node>(); 146 nodes.add(new Node("系統管理", "0")); 147 nodes.add(new Node("角色管理", "系統管理")); 148 nodes.add(new Node("資源管理", "系統管理")); 149 nodes.add(new Node("用戶管理", "系統管理")); 150 nodes.add(new Node("添加用戶", "用戶管理")); 151 nodes.add(new Node("修改用戶", "用戶管理")); 152 nodes.add(new Node("機票管理", "系統管理")); 153 154 Node tree = new Node(); 155 Node mt = tree.createTree(nodes); 156 System.out.println(tree.iteratorTree(mt)); 157 } 158 159 160 }
歐克歐克,代碼就是那麼多,一個文件搞定,有人可能不相信。好吧,火狐瀏覽器下看傳回來的參數是這樣的:
如今總該相信了吧?到此,基本介紹完啦,驚不驚喜,開不開心?好吧,本文主要的特色是可動態擴展樹中的節點,並且與數據庫的數據一一對應上。前臺用bootstrap的treeview
作展現,想必你看本文以前,已看過很多關於treeview的文章了吧。ps:紅色字體是本文重點。