一、引言
我今天做了一個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

