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

