场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点)
知识点:ComboTree、一般处理程序、递归、Json
效果如图
数据库表设计:unit_main
节点类设计:
1
2
3
4
5
6
7
8
9
10
11
12
|
public class Unit
{
public decimal id { get ; set ; }
public string text { get ; set ; }
public string state { get ; set ; }
public List<Unit> children { get ; set ; }
public Unit ()
{
this .children = new List<Unit>();
this .state = "open" ;
}
}
|
处理类设计:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
public class UnitComponent
{
ExeceteOralceSqlHelper SqlHelper= new ExeceteOralceSqlHelper(); //数据库处理类
public UnitParent GetUnit()
{
Unit rootUnit = new Unit();
rootUnit.id = 1000;
rootUnit.text = "BO API" ;
rootUnit.children = GetUnitList(0);
UnitRecursive(rootUnit.children);
return rootUnit;
}
/// <summary>
/// 递归查询部门
/// </summary>
/// <param name="units"></param>
private void UnitRecursive(List<Unit> units)
{
foreach (var item in units)
{
item.children = GetUnitList(item.id);
if (item.children != null && item.children.Count > 0)
{
item.state = "closed" ;
UnitRecursive(item.children);
}
}
}
/// <summary>
/// 通过parentID获取所有子部门
/// </summary>
/// <param name="parentID">父id</param>
/// <returns>返回Unit集合</returns>
private List<Unit> GetUnitList( decimal parentID)
{
List<Unit> unitLst = new List<Unit>();
string sql = string .Format( "select hh.unit_id,hh.unit_name from unit_main hh where hh.parent_id={0}" , parentID);
DataTable dt = SqlHelper.ExecuteDataTable(sql); //返回DataTable方法
if (dt != null && dt.Rows.Count > 0)
{
for ( int i = 0; i < dt.Rows.Count; i++)
{
Unit dtup = new Unit()
{
id = Convert.ToInt32(dt.Rows[i][ "unit_id" ]),
text = dt.Rows[i][ "unit_name" ].ToString()
};
unitLst.Add(dtup);
}
}
return unitLst;
}
}
|
下面,新建web应用程序-添加-一般处理程序,其中JavaScriptSerializer你可以换为NewtonSoft来处理
1
2
3
4
5
6
7
8
|
public void ProcessRequest(HttpContext context)
{
JavaScriptSerializer js = new JavaScriptSerializer();
context.Response.ContentType = "application/json" ;
UnitComponent uc = new SynUser.UnitComponent();
var unit = uc.GetUnit();
context.Response.Write( "[" + js.Serialize(unit) + "]" );
}
|
现在我们测试一下这个一般处理程序,如果像图片一样返回了结果说明正确:
好了,部门结构的数据准备好了,下开始写前台代码:
新建一个aspx页面,拖一个控件
1
|
<asp:TextBox ID= "tbUnit" runat= "server" Width= "280px" ></asp:TextBox>
|
引入相应的js,在script加入代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$( '#tbUnit' ).combotree({
url: , '/unit.ashx'
cascadeCheck: true ,
placeholder: "请选择部门" ,
method: 'get' ,
required: true ,
multiple: true ,
onChange: function (newValue, oldValue) {
computeunit();
},
onLoadSuccess: function (node, data) {
}
});
|
不知你有没有发现我选中的是应用管理服务中心、xiaobo、tech三个节点,但是xiaobo、tech是应用服务中心的叶子节点。需求要求,我们只需获取应用管理服务中心节点,不需要在获取xiaobo、tech。
所有要通过js遍历tree来获取我们想要的节点,computerunit方法是我们想要的。
思路为:递归获取被选的子节点,然后与所选的节点作差集,最后的得到的就是被选的节点(不包括全选的子节点)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
function computeunit() {
var arr = new Array();
var selectstr = $( "#tbUnit" ).combotree( "getValues" ).toString();
var select = selectstr.split( "," );
var t = $( '#tbUnit' ).combotree( 'tree' ); // get the tree object
var n = t.tree( 'getChecked' ); // get selected node
unitrecursive(t, n, arr);
alert(subtraction(select, arr).join( "," ));
}
/*计算数组差集
**返回结果数组
*/
function subtraction(arr1, arr2) {
var res = [];
for (var i = 0; i < arr1.length; i++) {
var flag = true ;
for (var j = 0; j < arr2.length; j++) {
if (arr2[j] == arr1[i]) {
flag = false ;
}
}
if (flag) {
res.push(arr1[i]);
}
}
return res;
}
/*获取被选父节点的子项目
**返回结果arr里
*/
function unitrecursive(t, nodes, arr) {
for (var i = 0; i < nodes.length; i++) {
if (!t.tree( 'isLeaf' , nodes[i].target)) {
var nn = t.tree( 'getChildren' , nodes[i].target);
for (var j = 0; j < nn.length; j++) {
arr.push(nn[j].id);
}
unitrecursive(t, nn, arr);
}
}
}
|
以上就是ASP.NET实现下拉树(Easy UI ComboTree)的全部思路,希望对大家的学习有所帮助。