zoukankan      html  css  js  c++  java
  • 爱上MVC3~MVC+ZTree实现对树的CURD及拖拽操作

    回到目录

    上一讲中,我们学习了如何使用zTree对一棵大树(大数据量的树型结构的数据表,呵呵,名称有点绕,但说的是事实)进行异步加载,今天这讲,我们来说说,如何去操作这棵大树,无非就是添加子节点,删除节点,编辑节点,节点之间的拖拽,节点位置的变化(排序)等等。

    事实上,jquery.ZTree的demo已经把前台JS代码给的很清晰了,我们只要稍加修改,然后把后台CS代码写好就可以了,我将demo的前台代码做了简单的处理,减化了些代码,项目架构使用microsoft mvc 3.0

    前台HTML代码如下:

    <link href="../../Scripts/JQuery-zTree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" />
    <script src="../../Scripts/JQuery-zTree/js/jquery-1.4.4.min.js"></script>
    <script src="../../Scripts/JQuery-zTree/js/jquery.ztree.all-3.5.min.js"></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; }
        a { text-decoration: underline; }
    </style>
    <script type="text/javascript">
        /*
       动态数据测试部分开始 */
        var log, className = "dark";
        var treeID = "treeDemo";
        var curDragNodes, autoExpandNode;
        var newCount = 1;
    
        //异步加载节点
        var setting4 = {
            data: {
                simpleData: {
                    enable: true,
                    idKey: "id",
                    pIdKey: "pId",
                    rootPId: null
                }
            },
            edit: {
                enable: true,
                editNameSelectAll: true,
                showRemoveBtn: showRemoveBtn,
                showRenameBtn: showRenameBtn,
                removeTitle: "删除",
                renameTitle: "编辑",
                drag: {
                    autoExpandTrigger: true,
                    prev: dropPrev,
                    inner: dropInner,
                    next: dropNext
                }
            },
            view: {
                addHoverDom: addHoverDom,
                removeHoverDom: removeHoverDom,
                selectedMulti: false
            },
            async: {
                //异步加载
                enable: true,
                url: "/ZTree/AsyncGetNodes",
                autoParam: ["id", "name", "pId"]
            },
            callback: {
                /*节点获取与展开回调*/
                beforeExpand: beforeExpand,
                onAsyncSuccess: onAsyncSuccess,
                onAsyncError: onAsyncError,
                /*编辑与删除回调*/
                beforeEditName: beforeEditName,
                beforeRemove: beforeRemove,
                beforeRename: beforeRename,
                onRemove: onRemove,
                onRename: onRename,
                /*拖动回调*/
                beforeDrag: beforeDrag,
                beforeDrop: beforeDrop,
                beforeDragOpen: beforeDragOpen,
                onDrag: onDrag,
                onDrop: onDrop,
                onExpand: onExpand
            }
        };
        function beforeEditName(treeId, treeNode) {
            className = (className === "dark" ? "" : "dark");
            var zTree = $.fn.zTree.getZTreeObj(treeID);
            zTree.selectNode(treeNode);
            return confirm("进入节点 -- " + treeNode.name + " 的编辑状态吗?");
        }
        function beforeRemove(treeId, treeNode) {
            className = (className === "dark" ? "" : "dark");
            var zTree = $.fn.zTree.getZTreeObj(treeID);
            zTree.selectNode(treeNode);
            return confirm("确认删除 节点 -- " + treeNode.name + " 吗?");
        }
        function beforeRename(treeId, treeNode, newName, isCancel) {
            className = (className === "dark" ? "" : "dark");
            if (newName.length == 0) {
                alert("节点名称不能为空.");
                var zTree = $.fn.zTree.getZTreeObj(treeID);
                setTimeout(function () { zTree.editName(treeNode) }, 10);
                return false;
            }
            return true;
        }
        function onRemove(e, treeId, treeNode) {
            $.ajax({
                url: '/ZTree/AsyncDelNodes', //url  action是方法的名称
                data: { id: treeNode.id },
                type: 'POST',
                success: function (data) {
                    alert(data);
                }
            });
    
        }
        function onRename(e, treeId, treeNode, isCancel) {
            alert("编辑了节点" + treeNode.id + " " + treeNode.name);
            $.ajax({
                url: '/ZTree/AsyncEditNodes', //url  action是方法的名称
                data: { id: treeNode.id, name: treeNode.name },
                type: 'POST',
                success: function (data) {
                    alert(data);
                }
            });
    
        }
        function showRemoveBtn(treeId, treeNode) {
            //return !treeNode.isFirstNode;
            return true;
        }
        function showRenameBtn(treeId, treeNode) {
            // return treeNode.isLastNode;
            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 zTree = $.fn.zTree.getZTreeObj(treeID);
                zTree.addNodes(treeNode, {
                    id: (100 + newCount), pId: treeNode.id, name: "new node" + newCount
                });
                $.ajax({
                    url: '/ZTree/AsyncAddNodes', //url  action是方法的名称
                    data: { id: (100 + newCount), pid: treeNode.id, name: "new node" + newCount },
                    type: 'POST',
                    success: function (data) {
                        //异常完成后,刷新父节点及下面所有子节点
                        zTree.reAsyncChildNodes(treeNode, "refresh");
                    }
                });
                newCount++;
                return false;
            });
        };
        function removeHoverDom(treeId, treeNode) {
            $("#addBtn_" + treeNode.tId).unbind().remove();
        };
        function createTree() {
            $.ajax({
                url: '/ZTree/AsyncGetNodes', //url  action是方法的名称
                data: { id: 0 },
                type: 'Get',
                dataType: "text", //可以是text,如果用text,返回的结果为字符串;如果需要json格式的,可是设置为json
                success: function (data) {
                    $.fn.zTree.init($("#" + treeID), setting4, eval('(' + data + ')'));
                },
                error: function (msg) {
                    alert(" 数据加载失败!" + msg);
                }
            });
        }
        function beforeExpand(treeId, treeNode) {
            if (!treeNode.isAjaxing) {
                return true;
            } else {
                alert("zTree 正在下载数据中,请稍后展开节点。。。");
                return false;
            }
        }
        function onAsyncSuccess(event, treeId, treeNode, msg) {
    
        }
        function onAsyncError() {
            alert(" 数据加载失败");
        }
        $(document).ready(function () {
            createTree();
        });
    
    
    
        function dropPrev(treeId, nodes, targetNode) {
    
            var pNode = targetNode.getParentNode();
            if (pNode && pNode.dropInner === false) {
                return false;
            } else {
                for (var i = 0, l = curDragNodes.length; i < l; i++) {
                    var curPNode = curDragNodes[i].getParentNode();
                    if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                        return false;
                    }
                }
            }
            return true;
        }
        function dropInner(treeId, nodes, targetNode) {
    
            if (targetNode && targetNode.dropInner === false) {
                return false;
            } else {
                for (var i = 0, l = curDragNodes.length; i < l; i++) {
                    if (!targetNode && curDragNodes[i].dropRoot === false) {
                        return false;
                    } else if (curDragNodes[i].parentTId && curDragNodes[i].getParentNode() !== targetNode && curDragNodes[i].getParentNode().childOuter === false) {
                        return false;
                    }
                }
            }
            return true;
        }
        function dropNext(treeId, nodes, targetNode) {
    
            var pNode = targetNode.getParentNode();
            if (pNode && pNode.dropInner === false) {
                return false;
            } else {
                for (var i = 0, l = curDragNodes.length; i < l; i++) {
                    var curPNode = curDragNodes[i].getParentNode();
                    if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                        return false;
                    }
                }
            }
            return true;
        }
        function beforeDrag(treeId, treeNodes) {
            className = (className === "dark" ? "" : "dark");
            for (var i = 0, l = treeNodes.length; i < l; i++) {
                if (treeNodes[i].drag === false) {
                    curDragNodes = null;
                    return false;
                } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) {
                    curDragNodes = null;
                    return false;
                }
            }
            curDragNodes = treeNodes;
            return true;
        }
        function beforeDragOpen(treeId, treeNode) {
            autoExpandNode = treeNode;
            return true;
        }
        function beforeDrop(treeId, treeNodes, targetNode, moveType, isCopy) {
            className = (className === "dark" ? "" : "dark");
            return true;
        }
        function onDrag(event, treeId, treeNodes) {
            className = (className === "dark" ? "" : "dark");
        }
        function onDrop(event, treeId, treeNodes, targetNode, moveType, isCopy) {
            className = (className === "dark" ? "" : "dark");
            $.ajax({
                url: '/ZTree/AsyncDragNodes', // url  action是方法的名称
                data: { id: treeNodes[0].id, pid: targetNode.id, name: treeNodes[0].name, moveType: moveType, isCopy: isCopy },
                type: 'POST',
                success: function (data) {
                }
            });
    
        }
        function onExpand(event, treeId, treeNode) {
            if (treeNode === autoExpandNode) {
                className = (className === "dark" ? "" : "dark");
            }
        }
    </script>
    
    <div class="zTreeDemoBackground left">
        <ul id="treeDemo" class="ztree"></ul>
    </div>

    面各种JS事件,所对应的MVC代码如下:

    #region 对节点的操作
            /// <summary>
            /// 得到一级子节点
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public string AsyncGetNodes(int? id)
            {
                var model = irepository.GetEntities()
                    .Where(i => i.ParentID == id).OrderBy(i => i.Sortable);
    
                return model.ToJson();
            }
            /// <summary>
            /// 添加节点
            /// </summary>
            /// <param name="id"></param>
            /// <param name="name"></param>
            /// <param name="pid"></param>
            /// <returns></returns>
            public string AsyncAddNodes(int id, string name, int pid)
            {
                try
                {
                    //得到父对象,但设置它的isParent属性
                    irepository.Modify(i => new Category
                      {
                          ID = pid,
                          IsParent = true,
                      });
    
                    var entity = new Category
                    {
                        Name = name,
                        ParentID = pid,
                        CreateDate = DateTime.Now,
                        Level = 1,
                        IsParent = false,
                    };
                    irepository.Add(entity);
    
                    return entity.ID.ToString();
                }
                catch (Exception ex)
                {
    
                    return ex.Message;
                }
    
            }
            /// <summary>
            /// 编辑节点(重命名)
            /// </summary>
            /// <param name="id"></param>
            /// <param name="name"></param>
            /// <returns></returns>
            public string AsyncEditNodes(int id, string name)
            {
                try
                {
                    irepository.Modify(i => new Category
                    {
                        ID = id,
                        Name = name,
                    });
                    return "操作成功";
                }
                catch (Exception ex)
                {
    
                    return ex.Message;
                }
            }
            /// <summary>
            /// 删除节点
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public string AsyncDelNodes(int id)
            {
                try
                {
                    irepository.Remove(irepository.GetEntity(i => i.ID == id));
                    return "操作成功";
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
            /// <summary>
            /// 拖拽节点
            /// </summary>
            /// <param name="id"></param>
            /// <param name="pid"></param>
            /// <param name="sortable"></param>
            /// <returns></returns>
            public string AsyncDragNodes(
                int id,
                int pid,
                string name,
                string moveType,
                bool isCopy)
            {
                try
                {
                    var parent = irepository.GetEntity(i => i.ID == pid);
                    var parentSons = irepository.GetEntities(i => i.ParentID == pid);
                    var current = irepository.GetEntity(i => i.ID == id);
                    if (moveType == "inner")
                        parent.isParent = true;
                    else if (parentSons == null || parentSons.Count() == 0)
                        parent.isParent = false;
                    if (isCopy)//复制,前台目前不能实现
                    {
                        irepository.Add(new Category
                        {
                            ParentID = pid,
                            Name = name,
                            CreateDate = DateTime.Now,
                        });
                    }
                    else
                    {
                        if (moveType == "inner")
                        {
                            current.ParentID = pid;
                            irepository.Modify(current);
                        }
                        else
                        {
                            current.ParentID = parent.ParentID;//同级移动时,与目标节点父ID相同
                            current.Sortable = moveType == "next"
                                ? parent.Sortable + 1
                                : parent.Sortable - 1;
                            irepository.Modify(current);
                        }
                    }
                    irepository.Modify(parent);
                    return "操作成功";
                }
                catch (Exception ex)
                {
    
                    return ex.Message;
                }
            }
            #endregion

    好了,上面的代码只是对树结果做的最基本的操作,其中拖拽时的复制操作(按着ctrl键,拖拽节点),后台没有进行实现。

    回到目录

  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/lori/p/3171655.html
Copyright © 2011-2022 走看看