Tree资源树的实战研究

简介: 最近小编在做项目的时候,遇到了一个动态添加资源树的问题,经过几番实践,终于实现了最终的结果,下面我会将自己的经历一点点抛给大家,希望读者尽情享受这顿盛宴。

背景简介:


   最近小编在做项目的时候,遇到了一个动态添加资源树的问题,经过几番实践,终于实现了最终的结果,下面我会将自己的经历一点点抛给大家,希望读者尽情享受这顿盛宴。

   这里,我们将实现如下图效果(功能介绍,通过选择年份显示左侧资源树,通过单击资源树在右侧表格中显示该指标中的档次信息):


20160407135302462.png


一、自己动手js拼接树实践


   HTML中就一句接收代码,Controller中将查询到的信息转换成json反到js中就可以了,这里主要是通过js控制树的一个拼接过程,如下代码:


<span style="font-family:KaiTi_GB2312;font-size:18px;">-
//通过年份查询定性指标,返回树-马康-2016-3-25 22:22:20
function QueryUnitObjectByYearType() {
    var nodeChild = document.getElementById("NodeChild");
    //获取下拉框中的年份
    var CheckYear = $('#CheckYear').combobox('getValue');
    //查询资源信息
    $.post("/SetQualitativeTargetLevel/QueryQualitativeTargetByYear?CheckYear=" + CheckYear, {}, function (data) {
        //添加的时候先清除div中的数据  
        $("#tree").empty();
        //将得到的集合按照指标类型去重放到res集合中
        var res = [];
        var json = {};
        for (var i = 0; i < data.length; i++) {
            if (!json[data[i].DictionaryName]) {
                res.push(data[i].DictionaryName);
                json[data[i].DictionaryName] = 1;
            }
        }
        //遍历去重之后的集合,显示到树的div中
        $.each(res, function (i, item) {
            if (item == "班子") {
                $("#tree").append("<ul id='UnittreeTarget' ><li><span>" + item + "</span></li></ul>");
            }
            else {
                $("#tree").append("<ul id='CardrestreeTarget' ><li><span>" + item + "</span></li></ul>");
            }
        });
        //遍历向div中添加查询到的指标信息
        $.each(data, function (i, item) {
            if (item.DictionaryName == "班子") {
                $("#UnittreeTarget").append("<ul><li><span>" + item.QualitativeTargetName + "</span></li></ul>");
            }
            else {
                $("#CardrestreeTarget").append("<ul><li><span>" + item.QualitativeTargetName + "</span></li></ul>");
            }
        });
    });
}
-</span>


   最终实现的效果图如下(这里只是将资源以一个树的结构显示出来了,并没有实现单击查询的功能):


20160407135506401.png


二、模仿老系统通过Controller中json转换拼接成树形结构的实战


   这种方法HTML中也只有一句接收代码,js中就一句传递代码,主要代码在Controller中来实现的,代码如下:

   调用后台数据的方法:


<span style="font-family:KaiTi_GB2312;font-size:18px;">-
#region QueryQualitativeTargetByYear 根据年份分页查询定性指标-马康-2016-3-4 0:17:45
        /// <summary>
        /// 根据年份分页查询定性指标-马康-2016-3-4 0:17:45
        /// </summary>
        /// <returns></returns>
        public string QueryQualitativeTargetByYear()
        {
            //实例化返回数据的载体-AllQuantifyResultInputViewModel(实例化伟涛写的ViewModel)
            List<SetQualitativeTargetViewModel> SetQualitativeTargetViewModel = new List<SetQualitativeTargetViewModel>();
            //获取界面传过来的考核年份
            string CheckYear1 = Request["CheckYear"];
            //将考核年份转换为int类型
            int CheckYear = Convert.ToInt32(CheckYear1);
            //通过考核年份调用服务端查询定量考核指标名称的方法(调用伟涛写的查询方法)
            SetQualitativeTargetViewModel = ISetQualitativeTarget.QueryQualitativeTargetByYear1(CheckYear);
            //将查询到的集合按照类型ID排序
            var str = from p in SetQualitativeTargetViewModel orderby p.DictionaryID select p;
            //实例化一个datatable
            DataTable dtTreeInfo = new DataTable();
            //添加列头
            dtTreeInfo.Columns.Add("id");
            dtTreeInfo.Columns.Add("name");
            //定义变量
            string DictionaryName = "";
            foreach (var item in str)
            {
                //判断去重
                if (DictionaryName != item.DictionaryName)
                {
                    //将不重复的值放到datatable中
                    DictionaryName = item.DictionaryName;
                    DataRow data = dtTreeInfo.NewRow();
                    data["id"] = item.DictionaryID;
                    data["name"] = item.DictionaryName;
                    dtTreeInfo.Rows.Add(data);
                }
            }
            string strJson = getJson(dtTreeInfo, SetQualitativeTargetViewModel);
            //将查询到的数据转换为Json返回到界面上  
            return strJson;
        }
        #endregion
-</span>


转换树形js的方法:


<span style="font-family:KaiTi_GB2312;font-size:18px;">-
 /// <summary>
        /// 节点树的组合-父节点树的遍历-马康-2016-4-5 14:00:35
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string getJson(DataTable dt, List<SetQualitativeTargetViewModel> SetQualitativeTargetViewModel)
        {
            //实例化承载字符串的json
            StringBuilder json = new StringBuilder();
            json.Append("[");
            foreach (DataRow dr in dt.Rows)
            {
                //将传进来的dt转换成只有子节点的dt
                DataTable dtChildren = new DataTable();
                //添加列头
                dtChildren.Columns.Add("id");
                dtChildren.Columns.Add("name");
                json.Append("{\"id\":" + dr["id"].ToString());
                json.Append(",\"text\":\"" + dr["name"].ToString() + "\"");
                json.Append(",\"state\":\"closed\"");
                //按照类型查询相应的定性指标
                var str = from m in SetQualitativeTargetViewModel where (m.DictionaryID.ToString() == dr["id"].ToString()) select m;
                //通过循环将查询到的定性指标存放到DataTable中
                foreach (var item in str)
                {
                    //实例化一个DataRow
                    DataRow data = dtChildren.NewRow();
                    //向DataRow中添加列头
                    data["id"] = item.QualitativeTargetID;
                    data["name"] = item.QualitativeTargetName;
                    //将dataRow中的数据添加到DataTable中
                    dtChildren.Rows.Add(data);
                }
                //调用D层方法获取dataTable
                if (dtChildren.Rows.Count == 0)
                {
                    return null;
                }
                //添加树字节点的json
                if (dt != null && dt.Rows.Count > 0)
                {
                    json.Append(",\"children\":[");
                    //调用将子节点转换成json树结构的方法
                    json.Append(DataTable2Json(dtChildren, dr["id"].ToString()));
                    json.Append("]");
                }
                json.Append("},");
            }
            if (dt.Rows.Count > 0)
            {
                json.Remove(json.Length - 1, 1);
            }
            //添加最后的]
            json.Append("]");
            //返回json
            return json.ToString();
        }
        #region DataTable2Json 子节点树的遍历-马康-2016-4-5 14:04:36
        /// <summary>  
        /// DataTable2Json 子节点树的遍历
        /// </summary>  
        /// <param name="dt"></param>  
        /// <returns></returns>  
        public static string DataTable2Json(DataTable dt, string pid)
        {
            //实例化json
            StringBuilder jsonBuilder = new StringBuilder();
            //循环,将数据转换成树结构的json
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                jsonBuilder.Append("{");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    //实例化并承接表示GUID
                    Guid id = new Guid(pid);
                    jsonBuilder.Append("\"");
                    //将列头字符转换成小写字母
                    dt.Columns[j].ColumnName = dt.Columns[j].ColumnName.ToLower();
                    //将列头为name转换成text
                    if (dt.Columns[j].ColumnName == "name") dt.Columns[j].ColumnName = "text";
                    //添加
                    jsonBuilder.Append(dt.Columns[j].ColumnName);
                    jsonBuilder.Append("\":\"" + dt.Rows[i][j].ToString() + "\",");
                }
                if (dt.Columns.Count > 0)
                {
                    jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                }
                jsonBuilder.Append("},");
            }
            if (dt.Rows.Count > 0)
            {
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            }
            return jsonBuilder.ToString();
        }
        #endregion 
-</span>


   这个实现起来比较麻烦,其中涉及了好多拼接转换,真正实现不建议用这样的方式,可以通过这个方式来锻炼一下自己的逻辑能力还是很不错的O(∩_∩)O~


三、使用Easyui通过js控制的实战


   小编这里实现的时候用的是zTree,下面是需要注意的地方以及对应的代码:

   HTML:树Easyui的引用,承载树的代码


<span style="font-family:KaiTi_GB2312;font-size:18px;">-
<script src="../../Content/zTree3.5/js/jquery.ztree.all-3.5.min.js"></script>
    <script src="../../Content/zTree3.5/js/jquery.ztree.core-3.5.min.js"></script>
    <script src="../../Content/zTree3.5/js/jquery.ztree.excheck-3.5.js"></script>
    <link href="../../Content/zTree3.5/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" />
 @*树的加载*@
        <div id="tree" class="easyui-panel" data-options="region:'west',split:true" title="定性指标体系" style="width: 200px;">
        </div>
-</span>


   js:资源树的查询方法,资源树的单击获取资源树节点ID之后查询内容的方法


<span style="font-family:KaiTi_GB2312;font-size:18px;">-
//通过年份查询定性指标,返回树-马康-2016-3-25 22:22:20
function QueryUnitObjectByYearType() {
    //获取下拉框中的年份
    var CheckYear = $('#CheckYear').combobox('getValue');
    //加载为分配角色树
    var tree = {
        /**
        * 所有的初始化的操作
        */
        setting:
        {
            //定义单击树节点的事件(js中必须有zTreeOnClick这个function)
            callback: {
                onClick: zTreeOnClick
            },
            //树的格式
            check: {
                enable: false,
                chkboxType: { "Y": "", "N": "" }
            },
            //树的数据
            data:
            {
                key:
                {
                    //要显示的字段
                    name: "QualitativeTargetName"
                },
                simpleData:
                {
                    enable: true,   //是否显示树形结构
                    //子节点
                    idKey: "QualitativeTargetID",
                    //父节点
                    pIdKey: "DictionaryID",
                    rootPId: "0"
                }
            },
            open:true
        }
    };
    //post提交,将查询条件传到controller中,并且接受controller返回回来的数据
    $.post("/SetQualitativeTargetLevel/QueryQualitativeTargetByYear?CheckYear=" + CheckYear, {}, function (result) {
        //jquery中的zTree方法,放置的容器($("#tree")),配置( tree.setting),数据(result)
        $.fn.zTree.init($("#tree"), tree.setting, result);
    });
}
//全局变量,为了单击的时候将单击的指标ID存入其中,添加的时候使用
var OnclickQualitativeTargetID = "";
//树的单击事件-根据年份和定性指标ID查询定性档次-马康-2016-4-6 22:03:34
function zTreeOnClick(e, treeId, treeNode) {
    //获取下拉框中的年份
    var CheckYear = $('#CheckYear').combobox('getValue');
    //获取单击的指标ID
    OnclickQualitativeTargetID = treeNode.QualitativeTargetID;
    //定性指标基础信息上面显示单击的定性指标名称
    document.getElementById("NodeChild").innerHTML = treeNode.QualitativeTargetName;
    //通过年份和指标Id查询未录入成绩的考核对象
    $('#dg').datagrid({
        url: '/SetQualitativeTargetLevel/QueryQualitativeTargetLevelByTargetYear?CheckYear=' + CheckYear + '&QualitativeTargetID=' + OnclickQualitativeTargetID,
        //title: '演示表格使用',  
        width: "100%",
        striped: true, //行背景交换                 
        fitColumns: true,
        idField: 'ID',
        loadMsg: '正在加载用户的信息...',
        pagination: true,
        singleSelect: false,
        pageList: [10, 20, 30, 40, 50],
        pageSize: 10,
        pageNumber: 1,
        queryParams: {
            searchName: $("#searchName").val()
        },
    }).datagrid("reload");
}
-</span>


   Controller:资源的汇集,这里需要特别注意的是父节点需要当成一行数据和子节点放在一起(可以通过数据库设计到一起,也可以通过代码转换拼接到一起)小编这里是在Controller中进行的拼接


<span style="font-family:KaiTi_GB2312;font-size:18px;">-
        #region QueryQualitativeTargetByYear 根据年份分页查询定性指标-马康-2016-3-4 0:17:45
        /// <summary>
        /// 根据年份分页查询定性指标-马康-2016-3-4 0:17:45
        /// </summary>
        /// <returns></returns>
        public ActionResult QueryQualitativeTargetByYear()
        {
            //实例化返回数据的载体-AllQuantifyResultInputViewModel(实例化伟涛写的ViewModel)
            List<SetQualitativeTargetViewModel> listSetQualitativeTargetVM = new List<SetQualitativeTargetViewModel>();
            //获取界面传过来的考核年份
            string CheckYear1 = Request["CheckYear"];
            //将考核年份转换为int类型
            int CheckYear = Convert.ToInt32(CheckYear1);
            //通过考核年份调用服务端查询定量考核指标名称的方法(调用伟涛写的查询方法)
            listSetQualitativeTargetVM= ISetQualitativeTarget.QueryQualitativeTargetByYear1(CheckYear);
            //用linq语句将查询到的集合按照类型ID排序,用这个排序的集合进行循环
            //(因为需要往listSetQualitativeTargetVM集合中添加数据,用listSetQualitativeTargetVM集合循环就会出错)
            var str = from p in listSetQualitativeTargetVM orderby p.DictionaryID select p;
            //定义一个变量来存放名称,去重的时候用到
            string DictionaryName = "";
            foreach (var item in str)
            {
                //实例化一个实体
                SetQualitativeTargetViewModel enSetQualitativeTargetVM = new SetQualitativeTargetViewModel();
                //判断去重
                if (DictionaryName != item.DictionaryName)
                {
                    //将不重复的值放到listSetQualitativeTargetVM集合中当成一条数据
                    DictionaryName = item.DictionaryName;
                    //将类型ID放入指标ID中
                    enSetQualitativeTargetVM.QualitativeTargetID = item.DictionaryID;
                    //将类型名称放入指标名称中
                    enSetQualitativeTargetVM.QualitativeTargetName = item.DictionaryName;
                    //将实体添加到list集合中
                    listSetQualitativeTargetVM.Add(enSetQualitativeTargetVM);
                }
            }
            //将查询到的数据转换为Json返回到界面上  
            return Json(listSetQualitativeTargetVM, JsonRequestBehavior.AllowGet);
        }
        #endregion
-</span>


   表结构:这里只需要用到下图红色字体的信息(类型名称是通过类型ID查询得到的)


20160407141012422.png


四、总结收获


   1、非常感谢在小编成长路上给予帮助与指导的师哥师姐

   2、遇到问题先寻找思路很重要

   3、有了思路就马上去践行,切记不要一直思考用那种方法更合适

   4、践行之后的总结很重要,将自己开始到最终的思路缕一遍

   5、搜查自己在实践过程中的局限性,寻求相应的解决办法

   6、不要太在意自己的初速度,要在后天培养自己的加速度(踏实走好每一就是一个培养加速度的践行)

   7、很长时间没有成效不要气馁焦躁,积极主动寻求帮助,站在巨人肩膀上

   8、始终相信自己一定可以揭取最后的桂冠GO GO GO O(∩_∩)O~

相关文章
|
数据可视化 大数据 BI
数据可视化大屏的设计规范和案例参考(使用AxureRP软件设计)
在信息化浪潮中,数据可视化不再仅限于单纯的数据呈现,而是逐渐演变为一种能够直观揭示复杂数据内在关联、趋势变化以及关键洞察的艺术形式。
1415 3
|
数据采集 自然语言处理 程序员
ChatGPT 调教日记(一):Markdown 解析器
ChatGPT 调教日记(一):Markdown 解析器
389 0
|
Linux
yum镜像源汇总
yum镜像源汇总
5101 0
|
7月前
|
设计模式 存储 程序员
六大设计原则
本文介绍了六大设计原则,包括单一职责、开闭原则、里氏替换、接口隔离、依赖倒置和迪米特法则。每项原则均通过定义、设计要点及代码示例进行说明。单一职责强调类的功能应单一;开闭原则提倡对扩展开放、对修改封闭;里氏替换要求子类能无缝替换父类;接口隔离主张拆分专用接口;依赖倒置鼓励面向抽象编程;迪米特法则减少类间依赖。掌握这些原则有助于编写高质量、可维护的代码,并为学习23种设计模式奠定基础。
208 0
|
Web App开发 前端开发 JavaScript
网页浏览和编辑DWG快速入门的方法(WEB CAD SDK)
MxDraw云图在线CAD解决方案,包括MxDraw、MxCAD开发包、图纸转换程序和后端服务。支持多种平台和CPU架构,推荐使用最新版Chrome或Edge浏览器。提供AutoCAD各版本dwg格式支持,具备三维和二维编辑功能。提供入门开发指南和功能丰富的示例。用户可下载开发包进行功能演示,包括在线预览和编辑CAD图纸。
1662 97
网页浏览和编辑DWG快速入门的方法(WEB CAD SDK)
|
Java API 网络安全
Java 发送邮件示例
本示例展示了如何使用Java编程语言发送电子邮件。通过利用JavaMail API,这段代码实现了从配置SMTP服务器,设置邮件属性,到发送邮件的全过程,为开发者提供了实用的参考。
884 12
|
存储 算法 Linux
Gzip的压缩级别
【4月更文挑战第29天】压缩级别
1255 1
|
编译器 C++
使用Visual Studio 2022 创建lib和dll并使用
本文介绍了如何在Visual Studio 2022中创建静态库(lib)和动态库(dll),并展示了如何使用这些库。文章详细说明了创建新项目、编写代码、生成库文件、配置项目属性以及编写测试代码的步骤,并提供了相应的截图和代码示例。作者还分享了在创建和使用库的过程中遇到的一些问题及其解决方案。
3284 0
使用Visual Studio 2022 创建lib和dll并使用
|
JavaScript 前端开发 Java
npm使用
npm使用
211 1
|
机器学习/深度学习 人工智能 PyTorch
VScode配置深度学习环境python+conda
VScode配置深度学习环境python+conda
1128 0