欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Asp.net下拉树的实现过程

程序员文章站 2024-02-18 12:39:52
场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点...

场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点)

知识点:combotree、一般处理程序、递归、json

效果如图

 Asp.net下拉树的实现过程

数据库表设计:unit_main

 Asp.net下拉树的实现过程

节点类设计:

 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) + "]");
}

现在我们测试一下这个一般处理程序,如果像图片一样返回了结果说明正确:

Asp.net下拉树的实现过程

好了,部门结构的数据准备好了,下开始写前台代码:

新建一个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) {
    
 }
});

 Asp.net下拉树的实现过程

不知你有没有发现我选中的是应用管理服务中心、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)的全部思路,希望对大家的学习有所帮助。