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