一、引言
我今天做了一個Ztree樹增刪改查菜單的功能。其中遇到了很多坑爹的問題,和大家講述一下。
二、代碼展示
1、Ztree樹前台代碼
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <link rel="stylesheet" href="${pageContext.request.contextPath }/pub/js/zTree/css/zTreeStyle/demo.css" type="text/css"> <link rel="stylesheet" href="${pageContext.request.contextPath }/pub/js/zTree/css/zTreeStyle/zTreeStyle.css" type="text/css"> <script type="text/javascript" src="${pageContext.request.contextPath}/pub/js/zTree/js/jquery.ztree.core-3.5.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/pub/js/zTree/js/jquery.ztree.excheck-3.5.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/pub/js/zTree/js/jquery.ztree.exedit-3.5.js"></script> <script type="text/javascript"> var setting = { async : { enable : true,//開啟異步加載處理 url : encodeURI(encodeURI("${pageContext.request.contextPath }/right/list.html")), autoParam : [ "id" ], dataFilter : filter, contentType : "application/json", type : "get" }, view : { expandSpeed : "", addHoverDom : addHoverDom, removeHoverDom : removeHoverDom, selectedMulti : false }, edit : { enable : true }, data : { simpleData : { enable : true } }, callback : { beforeRemove : beforeRemove, beforeRename : beforeRename, } }; function filter(treeId, parentNode, childNodes) { var nodes = JSON.parse(childNodes.data); if (!nodes) return null; for (var i = 0, l = nodes.length; i < l; i++) { nodes[i].name = nodes[i].name.replace(/\.n/g, '.'); } return nodes; } function beforeRemove(treeId, treeNode) { if (confirm("確認刪除節點--" + treeNode.name + "--嗎?")) { var param = "id=" + treeNode.id; $.post(encodeURI(encodeURI("${pageContext.request.contextPath }/right/deleteRight.html?" + param))); } else { return false; } } function beforeRename(treeId, treeNode, newName) { if (newName.length == 0) { alert("節點名稱不能為空."); return false; } var param = "id=" + treeNode.id + "&name=" + newName; $.post(encodeURI(encodeURI("${pageContext.request.contextPath }/right/editRight.html?" + param))); return true; } function addHoverDom(treeId, treeNode) { var sObj = $("#" + treeNode.tId + "_span"); if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return; var addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='add node' onfocus='this.blur();'></span>"; sObj.after(addStr); var btn = $("#addBtn_" + treeNode.tId); if (btn) btn.bind("click", function() { var Ppname = prompt("請輸入新節點名稱"); if (Ppname == null) { return; } else if (Ppname == "") { alert("節點名稱不能為空"); } else { var param ="&pId="+ treeNode.id + "&name=" + Ppname; var zTree = $.fn.zTree.getZTreeObj("treeDemo"); $.post( encodeURI(encodeURI("${pageContext.request.contextPath }/right/save.html?" + param)), function(data) { if ($.trim(data) != null) { var treenode = $.trim(data); zTree.addNodes(treeNode, { pId : treeNode.id, name : Ppname }, true); } }) } }); }; function removeHoverDom(treeId, treeNode) { $("#addBtn_" + treeNode.tId).unbind().remove(); }; $(document).ready(function() { $.fn.zTree.init($("#treeDemo"), setting); }); </script> <style type="text/css"> .ztree li span.button.add { margin-left: 2px; margin-right: -1px; background-position: -144px 0; vertical-align: top; *vertical-align: middle } </style> <div class="content_wrap"> <div class="zTreeDemoBackground left"> <ul id="treeDemo" class="ztree"></ul> </div> </div>
2、后台代碼
package com.hzwealth.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.hzwealth.common.vo.SysConstant; import com.hzwealth.common.vo.SysResult; import com.hzwealth.pojo.Right; import com.hzwealth.pojo.User; import com.hzwealth.service.RightService; import com.hzwealth.service.RoleService; /** * 菜單管理 * @author lixiaochao *create Date : 2017/1/6 17:08 */ @Controller @RequestMapping("/right") public class RightController { @Autowired private RightService rightService; @Autowired private RoleService roleService; /** * 修改菜單 * @param right * @return */ @RequestMapping("/editRight") @ResponseBody public SysResult editRight(Right right){ rightService.editRight(right); return SysResult.ok(); } /** * 刪除菜單 * @param rightId * @return */ @RequestMapping("/deleteRight") @ResponseBody public SysResult deleteRight(Long rightId){ rightService.deleteRight(rightId); return SysResult.ok(); } /** * 添加菜單 * @param right * @return */ @RequestMapping("/save") @ResponseBody public SysResult save(Right right){ rightService.addRight(right); return SysResult.ok(); } /** * 顯示信息菜單 * @param session * @return */ @RequestMapping("/list") @ResponseBody public SysResult list(HttpServletRequest request){ if(request==null|| request.getSession().getAttribute(SysConstant.CURRENT_USER_INFO)==null){ return SysResult.build(300, "當前用戶未登錄,請重新登錄"); } User user = (User)request.getSession().getAttribute(SysConstant.CURRENT_USER_INFO); String jsonStr = roleService.getRJsonStr(user.getRoleId()); //request.getSession().setAttribute("jsonStr", jsonStr); //System.out.println(request.getSession().getAttribute("jsonStr")); return SysResult.ok(jsonStr);//發送前台jsonStr json字符串 } }
其中roleService.getRJsonStr() 方法為:
/** * 展示菜單list 菜單管理模塊 * @param roleId * @return */ public String getRJsonStr(Long roleId){ List<Right> rightList = rightMapper.select(null); JSONArray array = new JSONArray(); for(Right right :rightList){ JSONObject jsonObject = new JSONObject(); jsonObject.put("id", right.getId()); jsonObject.put("name", right.getRightName()); jsonObject.put("pId", right.getParentId()); array.put(jsonObject); } return array.toString(); }
三、闡述問題及解決方案
1、問題一:第一次加載的時候不會顯示數據,刷頁面,第二次點開頁面才會加載出菜單。
解決方案:我后台用的是SysResult來返回結果,結果有返回信息,返回碼和傳到前台的數據。Ztree異步加載機制是先訪問那個url,然后在進入后台,然后在返回數據進入 filter,進入filter處理數據。childNodes是SysResult,所以直接用它來顯示,第一次根本顯示不出來。所以我后來用var node = childNodes.data來接受數據。但是出現了問題二的問題。
2、問題二:cannot read property 'replace' of undefined,不識別relace,
解決方案:我通過使用debugger(google瀏覽器可用,火狐我用不了),來查到node[i].name是一個雙引號,根本沒有拿到name后來我才知道,我們需要用js的JSON.parse(childNodes.data)來轉化。這是將json字符串轉換為json對象。問題解決。
四、總結
1、首先遇到問題,我們不要害怕,相反我們應該慶幸,因為每次遇到問題我們都是成長的過程。
2、遇到問題,冷靜思考,不要盲目的百度,google,學一樣東西,首先先把它的API大致看一看,遇到問題深入學習它的API。
Ztree API文檔,demo:http://download.csdn.net/download/xiaochaolovedan/9733857
3、遇到問題,最好的辦法大家都知道,就是debug,非常的方便,通過debugger來研究問題,一目了然。
4、少用eval,eval不安全,下面是詳細介紹:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval