无限分级和tree结构数据增删改【提供Demo下载】

无限分级

很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了。

说到无限分级,又要扯到递归调用了。(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据。当然,以下都是自己捣鼓的结果,非标准。谁有更好的设计望不吝啬赐教。

说来其实也简单,就是一个ID和父ID的关系。

以此类推,Id需要是唯一的,ParenId需要是Id列里面存在即可。这样我们就实现无限分级了,如果再加一列Sort排序就更完美了。

jstree插件

官方地址:https://www.jstree.com/

为什么要用这个插件?因为有方便的api给我们做数据绑定,且支持节点拖动来实现增删改,个人觉得这个功能挺强大的。

Demo

下面我们来基于jstree插件来实现无限分级数据操作。以区域数据操作为例,用Code First的方式来编写demo代码。

创建Region实体

为了配合插件自动生成的节点id,我们这里使用的Node和ParentNode来存储上下级关系(而不是上面说的id和parentid,但是实际效果是一样的)。

/// <summary>
/// 区域
/// </summary>
public class Region
{
    /// <summary>
    /// 主键id
    /// </summary>
    public int Id { get; set; }
    /// <summary>
    /// 名称
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 节点
    /// </summary>
    public string Node { get; set; }
    /// <summary>
    /// 父节点
    /// </summary>
    public string ParentNode { get; set; }

}

满足jstree插件的数据对象Dto

为了适应jstree插件的数据要求,我们需要把上面的数据转换成树状的数据对象。

/// <summary>
/// Dto
/// </summary>
public class RegionsTreeOutput
{
    /// <summary>
    /// Id
    /// </summary>
    public int RegionsId { get; set; }
    /// <summary>
    /// tree显示文本(对应region的name)
    /// </summary>
    public string text { get; set; }
    /// <summary>
    /// tree的id(对应Node)
    /// </summary>
    public string id { get; set; }
    /// <summary>
    /// 子节点数据(此属性就体现的数据的层级关系)
    /// </summary>
    public List<RegionsTreeOutput> children { get; set; }
}

数据转换

  #region GetRegionTree 初始化数据获取 的辅助方法
        public RegionsTreeOutput LoadRegions(string id, List<Region> inRegions, RegionsTreeOutput outRegions)
        {

            List<Region> regions = inRegions.Where(t => t.ParentNode == id).ToList();
            if (outRegions == null)//加载父节点
            {
                outRegions = ToTreeData(regions[0]);
                LoadRegions(outRegions.id, inRegions, outRegions);
            }
            else//加载子节点
            {
                outRegions.children = ToTreesData(regions);
                if (regions.Count > 0)
                {
                    for (int i = 0; i < regions.Count; i++)
                    {
                        LoadRegions(regions[i].Node, inRegions, outRegions.children[i]);//递归调用
                    }
                }
            }
            return outRegions;
        }

        public RegionsTreeOutput ToTreeData(Region region)
        {
            var treeData = new RegionsTreeOutput();
            treeData.id = region.Node;
            treeData.text = region.Name;
            treeData.RegionsId = region.Id;
            return treeData;
        }
        public List<RegionsTreeOutput> ToTreesData(List<Region> listRegion)
        {
            var regions = new List<RegionsTreeOutput>();
            for (int i = 0; i < listRegion.Count; i++)
            {
                regions.Add(ToTreeData(listRegion[i]));
            }
            return regions;
        }
        #endregion

初始化获取转换后的数据

 /// <summary>
 /// 初始化数据获取
 /// </summary>
 /// <returns></returns>
 public JsonResult GetResultData()
 {
     TreeDbContext db = new TreeDbContext();
     var regions = db.Regions.Where(t => true).ToList();
     var regionObj = LoadRegions("-1", regions, null);
     return Json(regionObj);
 }

以上后台的数据差不多就完成了。

前台数据加载

 $(function () {
            $.post("/Home/GetResultData", null, function (sData) {
                treeObj = $(‘#jstree_demo‘).jstree({
                    //, "checkbox"
                    ‘plugins‘: ["contextmenu", "dnd", "search", "state", "types", "wholerow"],
                    ‘core‘: {
                        "animation": 0,
                        "check_callback": true,
                        ‘force_text‘: true,
                        "themes": { "stripes": true },
                        ‘data‘: sData
                    },
                    "types": {
                        "default": {
                            "icon": "fa fa-folder icon-state-warning icon-lg"
                        },
                        "file": {
                            "icon": "fa fa-file icon-state-warning icon-lg"
                        }
                    },
                    "contextmenu": {
                        select_node: false,
                        show_at_node: true,
                        items: function (o, cb) {
                            //因为这里我们之后需要定义多个项,所以通过对象的方式返回
                            var actions = {};
                            //添加一个"新增"右键菜单
                            actions.create = {//这里的create其实阔以随意命名,关键是里面的 这里面的 action回调方法
                                "separator_before": false,//Create这一项在分割线之前
                                "separator_after": true,//Create这一项在分割线之后
                                "_disabled": false, //false表示 create 这一项可以使用; true表示不能使用
                                "label": "新增",  //Create这一项的名称 可自定义
                                "action": function (data) {  //点击Create这一项触发该方法,这理还是蛮有用的
                                    var inst = $.jstree.reference(data.reference),
                                         obj = inst.get_node(data.reference);//获得当前节点,可以拿到当前节点所有属性
                                    //新加节点,以下三行代码注释掉就不会添加节点
                                    inst.create_node(obj, {}, "last", function (new_node) {
                                        setTimeout(function () { inst.edit(new_node); }, 0);//新加节点后触发 重命名方法,即 创建节点完成后可以立即重命名节点
                                    });
                                }
                            };
                            if (o.id != "0001")//屏蔽对根节点的操作  “0001”改成根节点对应的真是id
                            {
                                //添加一个"重命名"右键菜单
                                actions.rename = {
                                    "separator_before": false,
                                    "separator_after": false,
                                    "_disabled": false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")),
                                    "label": "重命名",
                                    "action": function (data) {
                                        var inst = $.jstree.reference(data.reference),
                                                obj = inst.get_node(data.reference);
                                        inst.edit(obj);
                                    }
                                }
                                //添加一个"删除"右键菜单
                                actions.delete = {
                                    "separator_before": false,
                                    "icon": false,
                                    "separator_after": false,
                                    "_disabled": false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")),
                                    "label": "删除",
                                    "action": function (data) {
                                        var inst = $.jstree.reference(data.reference),
                                                obj = inst.get_node(data.reference);
                                        if (inst.is_selected(obj)) {
                                            inst.delete_node(inst.get_selected());
                                        }
                                        else {
                                            inst.delete_node(obj);
                                        }
                                    }
                                };
                            }
                            return actions;//返回右键菜单项
                        }
                    },
                });
            });
        });

其他操作

//删除节点
$(‘#jstree_demo‘).on(‘delete_node.jstree‘, function (e, data) {
            var id = data.node.original.RegionsId;
            $.ajax({
                type: "get",
                url: "/Home/DeleteRegion?id=" + id,
                success: function (sData) {

                }
            });
        });
//移动节点
$(‘#jstree_demo‘).on(‘move_node.jstree‘, function (e, data) {
            saveRegions(data);
        });
//修改名
$(‘#jstree_demo‘).on(‘rename_node.jstree‘, function (e, data) {
            saveRegions(data);
        });
//保存
function saveRegions(data) {
            var id = data.node.original.RegionsId;
            var name = data.node.text;//修改后的name
            //var oldName = data.old;//原name
            //var pNode = $(‘#jstree_demo‘).jstree().get_node(data.node.parent).original.RegionsId;
            var josnData = { "Id": id, "Node": data.node.id, "ParentNode": data.node.parent, "Name": name };
            $.ajax({
                url: "/Home/SaveRegions",
                data: josnData,
                success: function (sData) {
                    data.node.original.RegionsId = sData;
                    data.node.state.opened = false;//是否展开
                }
            });
        }

当然,记得修改或是删除要取RegionsId这个对应后台实体的ID。

通过按钮来操作增删改

function createTree() {
    var ref = $(‘#jstree_demo‘).jstree(true),
        sel = ref.get_selected();
    if (!sel.length) { return false; }
    sel = sel[0];
    sel = ref.create_node(sel, { "type": "file" });
    if (sel) {
        ref.edit(sel);
    }
};

function renameTree() {
    var ref = $(‘#jstree_demo‘).jstree(true),
        sel = ref.get_selected();
    if (!sel.length) { return false; }
    sel = sel[0];
    ref.edit(sel, function () {

    });
};

function deleteTree() {
    var ref = $(‘#jstree_demo‘).jstree(true),
        sel = ref.get_selected();
    if (!sel.length) { return false; }
    ref.delete_node(sel);
};

更加详细的细节请看demo。

链接:http://pan.baidu.com/s/1hrN5QvU 密码:c6b7

时间: 2024-10-06 23:04:17

无限分级和tree结构数据增删改【提供Demo下载】的相关文章

SSH登录与增删改查demo详解+源代码

点击下载,测试绝对可用SSH整合框架登录加增删改查demo 下载地址:http://download.csdn.net/detail/qq_33599520/9784679   一.框架概述 spring+Struts2+hibernate(SSH)整合框架是一种非常典型与实用的Web项目MVC架构,其中: Spring主要通过控制反转(IOC)与依赖注入(DI)控制对象的创建与维护,与实现面向切片编程(AOP),核心配置文件为:applicationContext.xml. Struts2是M

ztree : 增删改功能demo与自定义DOM功能demo的结合

最近有个项目要用ztree,需要用ztree自带的功能(增删改),也需要自定义DOM的功能(置顶). ztree的demo里有增删改的demo,也有自定义DOM的demo,但没有两者结合的. 所以我把demo改了一下,两个功能合在了一起. 上代码. <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - edit</TITLE> <meta http-equiv="content-ty

受老师邀请给学院国创队伍培训php,以一个实战新闻cms增删改查demo为例,写的文档讲义供大家参考

PHP实战基础——以一个新闻cms的增删改查为例 一.        环境配置 二.        数据库创建 三.        增删改查demo 连接数据库 <?php $link=mysql_connect("localhost","root","root"); mysql_select_db("demo",$link); mysql_query("set names utf8"); ?>

hibernate 入门增删改查demo

原文:hibernate 入门增删改查demo 源代码下载地址:http://www.zuidaima.com/share/1550463648238592.htm

ztree--插件实现增删改查demo(完整版)

ztree--插件实现增删改查demo(完整版) var setting = { async: { enable: true,       //开启异步加载处理 dataFilter: filter  //用于对 Ajax 返回数据进行预处理的函数 }, view: { addHoverDom: addHoverDom, removeHoverDom: removeHoverDom, selectedMulti: false, }, check: { enable: false }, data:

可删除超炫&amp;多种特效的Card视图(改造自cardsui-for-android开源项目),提供DEMO下载

       这里贴几个效果图,我做了一个gif的动态图,但是不知道为什么上传后图片不动,所以只能放在相册里. 如果大家想看动态的图片演示请点击后面的链接gif动态演示图片 实例Demo下载地址在本文最后 简单介绍 这个Demo主要是使用了cardsui-for-android开源项目,并且做了一些优化和改进: 1.自定义card视图 2.添加长按事件,避免误操作 3.长按后可以删除card,并播放选中动画 4.删除后浮现一个悬浮button 5.点击悬浮button可以恢复之前删除的card视

hibernate之增删改查demo

1 package dao; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.hibernate.Query; 7 import org.hibernate.SQLQuery; 8 import org.hibernate.Transaction; 9 10 import com.sun.org.apache.bcel.internal.generic.GETSTATIC; 11 12 import

jqGrid常用增删改查Demo及常见问题

1,jqGrid 第一次加载方法,和查询按钮可以执行的方法 方法1 jQuery("#tableId").jqGrid({  url: "/jqGrid/select.html",         //发送数据         postData: {"stock": $("#stock").val(), "name": $("#lastSales").val()},         //

大数据基本的 增删改差 Demo(资源来自网络本人属于收藏总结)

今天第一天接触大数据 做一些基本的增删改差,来这总结一下 ,资源来自网络本人属于收藏总结 这一篇只有demo合运行结果 ,下一篇有一点对代码的分析合自己的理解 先看一下数据库 的数据 查询数据 1 public static void main(String args[]) throws TRSException { 2 TRSConnection conn = new TRSConnection("http://127.0.0.1:5555", "admin",