不知不觉10月都结束了,又要到年底了。看看自己上次写过的文章后,已经2个月都没写东西了。真的是太忙了,本应该有好多东西可以写,但是没什么闲时间,每次想到写的时候,来点事就又给忘了。10月最后一天了,在忙也得把这篇文章写完,不然又得多一个空白月了。
这是之前带领成员开发一个小模块功能的时候,需要用到弹出窗口加载树状级联单位选择,最后决定用采用jQuery+EasyUI插件进行开发。但是在使用EasyUI中tree的插件时,碰到了不少麻烦。为了提供弹出树的显示速度,就采用异步加载数节点值,首先先加载根节点,然后根据点击的节点展开加载子节点。
往往结果和预期的都不一样,困惑了几天,展开后子节点是动态加载了,但是收缩后无法清空之前填充的数据;第二次在展开时,子节点又被重复加载了一遍,造成了数据重复显示,并没有提供清除子节点的方法。想尽了各种办法来解决这个问题,只能换另一种形式加载子节点的值了,把每一个节点值保存起来,判断是否已经存在,存在就不在去加载。
两种方法见实例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 var treeTitle = '选择列表';
2 var treeUrl = '../DataAshx/getTreeNode.ashx?pid=-1';
3 var nodeExp=false;
4 var nodekeep="";
5 var rows;
6 var noinf=0;
7 $(function() {
8 $('#treewindow').window({
9 title: treeTitle,
10 width: 400,
11 height: 400,
12 modal: true,
13 shadow: false,
14 closed: true,
15 resizable: false,
16 maximizable: false,
17 minimizable: false,
18 collapsible: false
19 });
20 });
21 function treeWindowOpen(name,rowIndx) {
22 $('#treewindow').window('open');
23 nodekeep="";
24 nodeExp=false;
25 rows=rowIndx.toString();
26 $('#basetree').tree({
27 checkbox: true,
28 animate: true,
29 url: treeUrl+"&coln="+escape(name.toString()),
30 cascadeCheck: true,
31 onlyLeafCheck: false,
32 onBeforeExpand: function(node, param) {
33 //------------第一种方法:异步加载子节点值-------------
34 // $('#basetree').tree('options').url = "../DataAshx/getTreeNode.ashx?pid=" + node.id+"&coln="+escape(name.toString());
35
36 //------------第二种方法:Ajax方法返回子节点Json值,使用append方法加载子节点
37 $.ajax({
38 type: "POST",
39 url: "../DataAshx/getTreeNode.ashx?pid=" + node.id+"&coln="+escape(name.toString())+"&casn="+escape(node.attributes.cas.toString()),
40 cache: false,
41 async: false,
42 dataType: "json",
43 success: function(data) {
44 if(nodekeep.indexOf(node.id)==-1)
45 {
46 append(data, node);
47 nodeExp = true;
48 }
49 }
50 });
51 $("#radCollapse").removeAttr("checked");
52 },
53 onLoadError:function(Error)
54 {
55 $.messager.alert('提示', '查询语句出错', 'error');
56 if(nodeExp==false)
57 {
58 $("#basetree").children().remove();
59 }
60 },
61 onLoadSuccess:function(success)
62 {
63 var child=$("#basetree").children().length;
64 noinf++;
65 if(child==0&&noinf>1)
66 {
67 $.messager.alert('提示', '数据不存在', 'Info');
68 }
69 }
70 });
71
72 }
73 function treeWindowClose() {
74 $('#treewindow').window('close');
75 nodekeep="";
76 nodekeep=false;
77 }
78 function treeWindowSubmit() {
79 var nodes = $('#basetree').tree('getChecked');
80 var info = '';
81 if (nodes.length > 0) {
82 for (var i = 0; i < nodes.length; i++) {
83 if (info != '') { info += ','; }
84 info += nodes[i].text;
85 }
86 //alert(JSON.stringify(nodes));
87 }
88 else {
89 var node = $('#basetree').tree('getSelected');
90 if (node != null) {
91 info = node.text;
92 }
93 }
94 $("#"+rows).val(info);
95 $('#treewindow').window('close');
96 nodekeep="";
97 nodeExp=false;
98 }
99 //全部展开
100 function collapseAll() {
101 $("#radCollapse").attr("checked", "checked");
102 var node = $('#basetree').tree('getSelected');
103 if (node) {
104 $('#basetree').tree('collapseAll', node.target);
105 } else {
106 $('#basetree').tree('collapseAll');
107 }
108 }
109 //全部收缩
110 function expandAll() {
111 var node = $('#basetree').tree('getSelected');
112 if (node) {
113 $('#basetree').tree('expandAll', node.target);
114 } else {
115 $('#basetree').tree('expandAll');
116 }
117 }
118 //增加子节点
119 function append(datas,cnode) {
120 var node = cnode;
121 $('#basetree').tree('append', {
122 parent: node.target,
123 data: datas
124 });
125 nodekeep+=","+node.id;
126 }
127 //重新加载
128 function reload() {
129 var node = $('#basetree').tree('getSelected');
130 if (node) {
131 $('#basetree').tree('reload', node.target);
132 } else {
133 $('#basetree').tree('reload');
134 }
135 }
136 //删除子节点
137 function remove() {
138 var node = $('#basetree').tree('getSelected');
139 $('#basetree').tree('remove',node.target);
140 }
页面getTreeNode.ashx返回树节点JSON格式数据:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ WebHandler Language="C#" Class="getTreeNode" %>
2
3 using System;
4 using System.Collections;
5 using System.Data;
6 using System.Linq;
7 using System.Web;
8 using System.Web.Services;
9 using System.Web.Services.Protocols;
10 using System.Xml.Linq;
11 using System.Collections.Generic;
12
13
14 public class getTreeNode : IHttpHandler, System.Web.SessionState.IRequiresSessionState
15 {
16
17 public void ProcessRequest(HttpContext context)
18 {
19 context.Response.ContentType = "text/plain";
20 DataTable dt = (DataTable)context.Session["viewmaintain"];
21 string parentId = string.Empty;
22 string resultStr = string.Empty;
23 string attributes = string.Empty;
24 string colName = string.Empty;
25 string sql = string.Empty;
26 string Casname = string.Empty;
27 bool colt = false;
28 string icon = "icon-profile";
29 if (!string.IsNullOrEmpty(context.Request.QueryString["pid"]))
30 {
31 parentId = context.Request.QueryString["pid"].ToString();
32 }
33 if ((!string.IsNullOrEmpty(context.Request.QueryString["coln"])) && (string.IsNullOrEmpty(context.Request.QueryString["casn"])))
34 {
35
36 colName = HttpUtility.UrlDecode(context.Request.QueryString["coln"].ToString());
37 if (dt != null)
38 {
39 bool pt = true;
40 while (pt)
41 {
42 for (int i = 0; i < dt.Rows.Count; i++)
43 {
44
45 Casname = dt.Rows[i]["view_colname"].ToString();
46 if (dt.Rows[i]["view_colname"].ToString() == colName)
47 {
48 if (dt.Rows[i]["view_cas"].ToString() != null&&dt.Rows[i]["view_cas"].ToString() !="")
49 {
50 colName = dt.Rows[i]["view_cas"].ToString();
51 }
52 else
53 {
54 colt = true;
55 sql = dt.Rows[i]["view_sql"].ToString();
56 pt = false;
57 }
58
59 break;
60 }
61 }
62 }
63
64 }
65 }
66 if ((!string.IsNullOrEmpty(context.Request.QueryString["casn"])) && (!string.IsNullOrEmpty(context.Request.QueryString["coln"])))
67 {
68
69 string casnName = HttpUtility.UrlDecode(context.Request.QueryString["casn"].ToString());
70 colName = HttpUtility.UrlDecode(context.Request.QueryString["coln"].ToString());
71 if (dt != null)
72 {
73 for (int i = 0; i < dt.Rows.Count; i++)
74 {
75 Casname = dt.Rows[i]["view_colname"].ToString();
76 if (dt.Rows[i]["view_cas"].ToString() == casnName && casnName != colName)
77 {
78 colt = true;
79 sql = dt.Rows[i]["view_sql"].ToString();
80 break;
81 }
82 }
83 }
84 }
85 try
86 {
87 if (parentId != "" && colt == true)
88 {
89 //此处省略得到数据列表的代码
90 List<TreeInfo> ltree = DAL_TreeInfo.GetItemValue(parentId, sql);
91 resultStr = "";
92 resultStr += "[";
93 if (ltree.Count > 0)
94 {
95 foreach (TreeInfo item in ltree)
96 {
97 attributes = "";
98 attributes += "{\"cas\":\"" + Casname;
99 attributes += "\",\"val\":\"" + item._text + "\"}";
100 resultStr += "{";
101 resultStr += string.Format("\"id\": \"{0}\", \"text\": \"{1}\", \"iconCls\": \"{2}\", \"attributes\": {3}, \"state\": \"closed\"", item._id, item._text, icon, attributes);
102 resultStr += "},";
103 }
104 resultStr = resultStr.Substring(0, resultStr.Length - 1);
105 }
106 resultStr += "]";
107 }
108 else
109 {
110 resultStr = "[]";
111 }
112 }
113 catch (Exception ex)
114 {
115 resultStr = "出错";
116 }
117
118 context.Response.Write(resultStr);
119 }
120
121 public bool IsReusable
122 {
123 get
124 {
125 return false;
126 }
127 }
128 }
关键性的代码都已经在上面了,目前也就只能想到这种办法来解决了,有时间的话可以给tree扩展一下,添加一个清除子节点的方法,这样应该实现起来会更容易方便。
小弟在此献丑了,不知道各位专家、同仁有没有遇到类似的问题,或者有其它更好的解决办法,欢迎在这交流。
同时也感谢各位抽出宝贵的时间阅读文章,让我们共同进步,共同分享交流,在节省他人的时间就是提高自己~~~
作者:zeke
出处:http://zhf.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。