Tree资源树的实战研究

前端之家收集整理的这篇文章主要介绍了Tree资源树的实战研究前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

背景简介:

最近小编在做项目的时候,遇到了一个动态添加资源树的问题,经过几番实践,终于实现了最终的结果,下面我会将自己的经历一点点抛给大家,希望读者尽情享受这顿盛宴。
这里,我们将实现如下图效果(功能介绍,通过选择年份显示左侧资源树,通过单击资源树在右侧表格中显示该指标中的档次信息):

一、自己动手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,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>

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

二、模仿老系统通过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查询得到的)

四、总结收获

1、非常感谢在小编成长路上给予帮助与指导的师哥师姐 2、遇到问题先寻找思路很重要 3、有了思路就马上去践行,切记不要一直思考用那种方法更合适 4、践行之后的总结很重要,将自己开始到最终的思路缕一遍 5、搜查自己在实践过程中的局限性,寻求相应的解决办法 6、不要太在意自己的初速度,要在后天培养自己的加速度(踏实走好每一就是一个培养加速度的践行) 7、很长时间没有成效不要气馁焦躁,积极主动寻求帮助,站在巨人肩膀上 8、始终相信自己一定可以揭取最后的桂冠GO GO GO O(∩_∩)O~

猜你在找的XML相关文章