尚籌網04選單維護
阿新 • • 發佈:2020-07-21
樹形結構基礎知識介紹
選單維護:頁面顯示樹形結構
目標
將資料庫中查詢得到的資料到頁面上顯示出來.
思路
資料庫查詢全部-》java物件組裝-》頁面上使用zTree顯示
程式碼:將資料在java程式碼中組裝成樹形結構
MenuExample
// 主鍵 private Integer id; // 父節點 private Integer pid; private String name; private String url; // 圖示樣式 private String icon; // 儲存子節點的集合,初始化避免空指標異常 private List<Menu> children=newArrayList<>(); //控制節點預設狀態,true開啟 private Boolean open=true;
service方法
@Override public List<Menu> getAll() { return menuMapper.selectByExample(new MenuExample()); }
Controller方法(構建二叉樹)
思路
- 整體的思路是組裝二叉樹
- 找到根節點
- 為父節點新增子節點
@RequestMapping("/menu/get/whole/tree.json") public ResultEntity<Menu> getWholeTreeNew(){//1、查詢全部的Menu物件 List<Menu> menus = menuService.getAll(); //2、宣告一個變數用來儲存找到根節點 Menu root = null; //3、建立Map物件用來儲存id和Menu物件的對應關係便於查詢父節點 Map<Integer,Menu> menuMap = new HashMap<>(); //4、遍歷menuList填充menuMap for (Menu menu : menus) { Integer id = menu.getId(); menuMap.put(id,menu); }//5、再次遍歷menuList查詢根節點、組裝父子節點 for (Menu menu : menus) { //6、獲取當前menu物件的pid屬性值 Integer pid = menu.getPid(); //7、如果pid為null,判定為根節點 if (pid == null){ root = menu; //8、如果當前節點是根節點,那麼繼續執行 continue; } //9、如果pid不為null,說明當前節點有父節點,那麼可以根據 //pid到menuMap中查詢對應的Menu物件 Menu father = menuMap.get(pid); //10、將當前節點存入父節點的children集合 father.getChildren().add(menu); } //11、經過上面的運算,根節點包含了整個樹形結構,返回根節點 return ResultEntity.sucessWithData(root); }
程式碼:跳轉頁面
<mvc:view-controller path="/menu/to/page.html" view-name="menu-page"/>
<%--//zTree引入--%> <link rel="stylesheet" href="static/ztree/zTreeStyle.css"/> <script type="text/javascript" src="static/ztree/jquery.ztree.all-3.5.min.js"></script> <script src="static/commonjs/my-menu.js"></script>
程式碼:在頁面上使用真實資料
$.ajax({ "url":"menu/get/whole/tree.json", "type":"post", "dataType":"json", "success":function (response) { var result = response.result; if (result == "SUCCESS"){ // 建立json物件儲存zTree所做的設定 var setting = { "view":{ //加圖示 "addDiyDom":myAddDiyDom, "addHoverDom":myAddHoverDom, "removeHoverDom":myRemoveHoverDom }, "data":{ "key":{ "url":"maomi" } } }; var zNodes=response.data; // 初始化樹結構 // ,不要寫成. $.fn.zTree.init($("#treeDemo"),setting,zNodes); } if (result == "FAILD"){ layer.msg(response.message) } } });
程式碼:修改預設圖示為真實圖示
//修改預設圖示 function myAddDiyDom(treeId,treeNode){ //控制span標籤 var spanId=treeNode.tId+"_ico"; //刪除舊class //新增新的class $("#"+spanId) .removeClass() .addClass(treeNode.icon); }
程式碼實現點了不跑
當點選時,zTree沒有找到maomi這個key就不會發送資料
程式碼:顯示按鈕組
思路步驟
- 控制<span>A</span>是否顯示
- 明確具體按鈕的新增規則
- 準備好按鈕的html標籤
- 根據按鈕規則把按鈕填充到span中
myremoveHoverDom(treeId,treeNode)函式
//滑鼠移入範圍是刪除按鈕組 function myRemoveHoverDom(treeId,treeNode) { var btnGroupId=treeNode.tId+"_btnGrp"; $("#"+btnGroupId).remove() }
myAddHoverDom(treeId,treeNode)函式
//滑鼠移入範圍是新增按鈕組 function myAddHoverDom(treeId,treeNode) { //定id刪除的時候定位 var btnGroupId=treeNode.tId+"_btnGrp"; if ($("#"+btnGroupId).length>0){ return;} //準備各個按鈕的HTML標籤onclick='showAddModal(this)' var addBtn="<a id='"+treeNode.id+"' class='addBtn btn btn-info dropdown-toggle btn-xs ' style='margin-left:10px;padding-top:0px;' href='#' title='新增許可權資訊'> <i class='fa fa-fw fa-plus rbg '></i></a>"; var editBtn="<a id='"+treeNode.id+"' class='editBtn btn btn-info dropdown-toggle btn-xs ' style='margin-left:10px;padding-top:0px;' href='#' title='修改許可權資訊'> <i class='fa fa-fw fa-edit rbg '></i></a>" var removeBtn="<a id='"+treeNode.id+"' class='removeBtn btn btn-info dropdown-toggle btn-xs ' style='margin-left:10px;padding-top:0px;' href='#' title='刪除許可權資訊'> <i class='fa fa-fw fa-times rbg '></i></a>"; // 獲取當前節點的級別資料 var level=treeNode.level; var btnHTML=""; //各級別不同操作,按鈕的不同 if (level ==0){ btnHTML=addBtn;} if (level ==1){ btnHTML=addBtn+" "+editBtn+" "+removeBtn; var length=treeNode.children.length; if (length == 0){ btnHTML =addBtn+" "+removeBtn; } } if (level ==2){ btnHTML=editBtn+" "+removeBtn+" "; } var anchorId=treeNode.tId+"_a"; $("#"+anchorId).after("<span id='"+btnGroupId+"'>"+btnHTML+"</span>") }
程式碼:把生成樹形結構的程式碼封裝到函式
在menu-page.jsp渲染時呼叫即可
$(function () { //呼叫專門封裝好的函式初始化樹形結構 generateTree(); });
選單維護:新增子節點
目標
給當前節點新增子節點,儲存到資料庫並重新整理樹形結構的顯示
前端程式碼
//準備各個按鈕的HTML標籤onclick='showAddModal(this)' var addBtn = "<a id='" + treeNode.id + "' class='addBtn btn btn-info dropdown-toggle btn-xs ' style='margin-left:10px;padding-top:0px;' href='#' title='新增許可權資訊'> <i class='fa fa-fw fa-plus rbg '></i></a>"; var editBtn = "<a id='" + treeNode.id + "' class='editBtn btn btn-info dropdown-toggle btn-xs ' style='margin-left:10px;padding-top:0px;' href='#' title='修改許可權資訊'> <i class='fa fa-fw fa-edit rbg '></i></a>" var removeBtn = "<a id='" + treeNode.id + "' class='removeBtn btn btn-info dropdown-toggle btn-xs ' style='margin-left:10px;padding-top:0px;' href='#' title='刪除許可權資訊'> <i class='fa fa-fw fa-times rbg '></i></a>";
給“+”按鈕繫結單機響應函式
//給新增子節點按鈕繫結單擊響應函式 $("#treeDemo").on("click", ".addBtn", function () { //將當前節點的id,作為新節點的pid儲存到全域性變數 window.pid = this.id; //開啟模態框 $("#menuAddModal").modal("show"); return false; });
給新增子節點的模態框中的儲存按鈕繫結單擊響應函式
$("#menuSaveBtn").click(function () { //收集表單項中使用者輸入的資料 var name = $.trim($("#menuAddModal [name=name]").val()); var url = $.trim($("#menuAddModal [name=url]").val()); //單選按鈕要定位到"被選中"的那一個 var icon = $("#menuAddModal [name = icon]:checked").val; //傳送ajax請求 $.ajax({ "url": "menu/save.json", "type": "post", "data": { "pid": window.pid, "name": name, "url": url, "icon": icon }, "datatype": "json", "success": function (response) { alert(response); var result = response.result; if (response === "SUCCESS") { layer.msg("操作成功"); // 重新載入樹形結構, // 注意:要在確認伺服器端完成儲存操作後再重新整理 // 否則有可能重新整理不到最新的資料,因為這裡是非同步的 generateTree(); } if (result === "FAILED") { layer.msg("操作失敗" + response.message); } }, "error": function (response) { layer.msg(response.status + " " + response.statusText) } }); //關閉模態框 $("#menuAddModal").modal("hide"); //清空表單 //JQuery物件呼叫click()函式,裡面不傳任何引數,相當於使用者點選一了下1 $("#menuResetBtn").click(); });
後端程式碼
Controller
@RequestMapping("/menu/save.json") public ResultEntity<String> saveMenu(Menu menu){ menuService.saveMenu(menu); return ResultEntity.successWithoutData(); }
service程式碼
@Override public void saveMenu(Menu menu) { menuMapper.insert(menu); }
選單維護:更新節點
目標
修改當前節點的基本屬性.不更換父節點.
思路
前端程式碼
給編輯按鈕繫結單擊響應函式
//給編輯按鈕繫結單擊響應函式 $("#treeDemo").on("click", ".editBtn", function () { //將當前節點的id儲存到全域性變數 window.id = this.id; //開啟模態框 $("#menuEditModal").modal("show"); //獲取zTreeObj物件 var zTreeObj = $.fn.zTree.getZTreeObj("treeDemo"); //根據id屬性查詢節點物件 //用來搜尋節點的屬性名 var key = "id"; //用來搜尋節點的屬性值 var value = window.id; var currentNode = zTreeObj.getNodeByParam(key, value); //回顯表單資料 $("#menuEditModal [name=name]").val(currentNode.name); $("#menuEditModal [name=url]").val(currentNode.url); //回顯radio可以這樣理解:被選中的radio的value屬性可以組成一個數組 //然後再用這個陣列設定回radio,就能夠把對應的值選中 $("#menuEditModal [name=icon]").val([currentNode.icon]); return false; }); //給更新模態框中的更新按鈕繫結單擊響應函式 $("#menuEditBtn").click(function () { //收集表單資料 var name = $("#menuEditModal [name = name]").val(); var url = $("#menuEditModal [name=url]").val(); var icon = $("#menuEditModal [name=icon]:checked").val(); //傳送ajax請求 $.ajax({ "url": "menu/update.json", "type": "post", "data": { "id": window.id, "name": name, "icon": url, "url": url, "icon": icon }, "datatype": "json", "success": function (response) { var result = response.result; if (result === "SUCCESS") { layer.msg("操作成功"); // 重新載入樹形結構,注意:要在確認伺服器端完成儲存操作後再重新整理 // 否則有可能重新整理不到最新的資料,因為這裡是非同步的 generateTree(); } if (result === "FAILED") { layer.msg("操作失敗" + response.message); } }, "error": function (response) { layer.msg(response.status + " " + response.statusText); } }); //關閉模態框 $("#menuEditModal").modal("hide"); });
後端程式碼
controller程式碼
@RequestMapping("/menu/update.json") public ResultEntity<String> updateMenu(Menu menu){ menuService.updateMenu(menu); return ResultEntity.successWithoutData(); }
service程式碼
@Override public void updateMenu(Menu menu) { // 由於 pid 沒有傳入,一定要使用有選擇的更新,保證“pid”欄位不會被置空 menuMapper.updateByPrimaryKeySelective(menu); }
選單維護:刪除節點
目標
刪除當前節點
思路
前端程式碼
給❎按鈕繫結單擊響應函式
//給叉按鈕繫結單擊響應函式 $("#treeDemo").on("click", ".removeBtn", function () { //將當前節點的id儲存到全域性變數 window.id = this.id; //開啟模態框 $("#menuConfirmModal").modal("show"); //獲取zTreeObj物件 var zTreeObj = $.fn.zTree.getZTreeObj("treeDemo"); //根據id屬性查詢節點物件 //用來搜尋節點的屬性名 var key = "id"; //用來搜尋節點的屬性值 var value = window.id; var currentNode = zTreeObj.getNodeByParam(key, value); $("#removeNodeSpan").html("【" + "<i class = '" + currentNode.icon + "' > </i>" + currentNode.name + "】"); return false; }); //給更新模態框中的更新按鈕繫結單擊響應函式 $("#confirmBtn").click(function () { //傳送ajax請求 $.ajax({ "url": "menu/remove.json", "type": "post", "data": { "id": window.id }, "datatype": "json", "success": function (response) { var result = response.result; if (result === "SUCCESS") { layer.msg("操作成功"); // 重新載入樹形結構,注意:要在確認伺服器端完成儲存操作後再重新整理 // 否則有可能重新整理不到最新的資料,因為這裡是非同步的 generateTree(); } if (result === "FAILED") { layer.msg("操作失敗" + response.message); } }, "error": function (response) { layer.msg(response.status + " " + response.statusText); } }); //關閉模態框 $("#menuConfirmModal").modal("hide"); });
後端程式碼
@RequestMapping("/menu/remove.json") public ResultEntity<String> deleteMenu(Integer id){ menuService.deleteByPrimaryKey(id); return ResultEntity.successWithoutData(); }
service程式碼
@Override public void deleteByPrimaryKey(Integer id) { menuMapper.deleteByPrimaryKey(id); }