Ztree树增删改查菜单,遇到的问题总结

一、引言

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

原文地址:https://www.cnblogs.com/lixiaochao/p/6269689.html