Asp.net下拉树的实现过程
程序员文章站
2024-02-18 12:39:52
场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点...
场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点)
知识点:combotree、一般处理程序、递归、json
效果如图
数据库表设计:unit_main
节点类设计:
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"; } }
处理类设计:
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来处理
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页面,拖一个控件
<asp:textbox id="tbunit" runat="server" width="280px"></asp:textbox>
引入相应的js,在script加入代码
$('#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方法是我们想要的。
思路为:递归获取被选的子节点,然后与所选的节点作差集,最后的得到的就是被选的节点(不包括全选的子节点)
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)的全部思路,希望对大家的学习有所帮助。