MVC小系列(十五)【MVC+ZTree实现对树的CURD及拖拽操作】

根据上一讲的可以加载一棵大树,这讲讲下如果操作这颗大树

<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键,拖拽节点),后台没有进行实现。

时间: 2024-07-29 16:58:05

MVC小系列(十五)【MVC+ZTree实现对树的CURD及拖拽操作】的相关文章

MVC小系列(五)

在过滤器里引入重定向 过滤器的引入:如果用户进行一个操作,但没有登录,可以在Post方法上加个过滤器以验证用户是否登录,如果登录成功,则继续进行操作,如果没有登录,则实现Url的重定向,进行登录页 授权过滤器可以继承自AuthorizeAttribute类,通常重写它的OnAuthorization() 方法,将要验证的逻辑写在方法里,而filterContext就是当前web请求的上下文,如果希望得到当前页面的Request,Response,HttpContext,RouteData等信息,

S3C2416裸机开发系列十五_GCC下uCOS的移植(1)

S3C2416裸机开发系列十五 GCC下uCOS的移植(1) 象棋小子    1048272975 操作系统是用来管理系统硬件.软件及数据资源,控制程序运行,并为其它应用软件提供支持的一种系统软件.根据不同的种类,又可分为实时操作系统.桌面操作系统.服务器操作系统等.对于一些小型的应用,对系统实时性要求高,硬件资源有限等的情况下,应尽量避免使用复杂庞大的操作系统(如Linux),使用小型的实时操作系统(如uCOS)更能满足应用的需求.笔者此处就uCOS-II的移植作一个简单的介绍. 1. 代码准

S3C2416裸机开发系列十五_GCC下uCOS的移植(2)

S3C2416裸机开发系列十五 GCC下uCOS的移植(2) 象棋小子    1048272975 4. uCOS配置 uCOS是可裁减实时操作系统,可以根据实际的应用对内核未使用到的功能进行裁减,以进一步节省系统宝贵的硬件资源,通常可用的uCOS-II内核代码在6K~26K,这在uCOS-II配置文件os_cfg.h中进行配置,这个配置文件在源码目录为os_cfg_r.h,从目录中拷贝添加到uCOS/uCOS-II/Cfg目录中,并重命名为os_cfg.h. #ifndef OS_CFG_H

MVC小系列(十二)【RenderAction和RenderPartial区别】

二者作用:RenderAction:渲染分部视图到页面上,要求提供Action和控制器名称RenderPartial:渲染分部视图到页面上,要求提供分部视图的名称,即路径,如果是在当前控制下或者shared下的页面,可以直接写名称即可 区别:RenderAction:通过控制器在aciton,即HttpGet特性RenderPartial:不通过控制器和aciton,即使有也不走这个,一般使用RenderPartial时,都是把数据写在页面上, 注意:如果有多个视图中的表单分别有提交动作,必须使

MVC小系列(十)【PartialView中的页面重定向】

在mvc的每个Action中,都可以指定一种返回页面的类型,可以是ActionResult,这表示返回的页面为View或者是一个PartialView, 在以Aspx为页面引擎时,PartialView被称为分部视图,扩展名为ASCX,与webform的用户控件一样,是页面的一部分,而使用Razor为页面引擎时,partialView扩展名还是cshtml 第一种情况,在Partialview中进行表单提示操作后,需要返回一个PartialView来填充原来的partialView的内容,这种情

MVC小系列(十六)【在控制器级别或具体Action级别上动态设定模板页(Layout)】

方法就是使用:ActionFilterAttribute它的几个方法:OnActionExecuted,OnActionExecuting,OnResultExecuted和OnResultExecuting,它们记录一个action从加载到页面最终显示在浏览器的全过程,这个东西一般用在页面权限验证,LayOut页面控制上这里面的几个方法执行顺序:OnActionExecuting action执行前 OnActionExecuted action执行后 OnResultExecuting 页面

MVC小系列(十一)【Html.BeginForm与Ajax.BeginForm】

Html.BeginForm与Ajax.BeginForm都是mvc的表单元素,前者是普通的表单提交,而后者是支持异步的表单提交,直接用mvc自带的Ajax.BeginForm就可以很容易完成一个异步的表单提交动作 第一种普通提交几种方式 1 @using (Html.BeginForm()) {} //提交到当前页面 2 3 @using (Html.BeginForm(new {} )) {} //提交到当前页面,并可以传递参数 4 5 @using (Html.BeginForm("act

MVC小系列(二)

Razor 模板引擎 Razor模板页:它使我们不用再使用master模板了 一 :@Url.Content:是可以加载CSS和JS等文件比如: <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jq

Cocos2d-x 3.x 图形学渲染系列十五

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解>电子工业出版社等. 在游戏开发中或者是游戏程序员招聘中,都有关于图形学或者引擎高级程序职位.凡是涉及到这些职位的招聘,对于此职位的开发人员都需要会Shader编程或者说GPU编程,同时他们的薪资也是比较高的.目前国内掌握图形学编程的人不是很多,物以稀为贵.Shader编程的主要目的是协