因为业务要求做一个组织架构,就是理论上可以无限级的tree。第一次自己尝试写一棵树,分享一下过程。
解决这类不清楚有多少级节点的问题,用递归是最清爽的一个办法。
页面上最后展现的形式
整理一下逻辑:前台需要的是一个List<HashMap>,list里每一个对象应该有一个key = "children" 对应的value 是List<HashMap>(子级节点数组),同理每一个子集节点还要有key="children"对应List<HashMap>,这样就形成了递归;
java后台:
首先根据我的一张组织架构的表如下
[img]http://dl2.iteye.com/upload/attachment/0115/3582/a65b5eb8-ca57-306f-9f7f-377e728d1be3.png[/img]
我们只需要关心 department_id 和 department_parent_id。
先把所有的department查询出来组成一个List<HashMap>,
下面我写了一个递归把没有层级结构的的List<HashMap>转化成前台需要的List<HashMap>
返回给页面
assembleChildrenTree中判断如果children长度不为0,再次调用assembleChildrenTree传入chidlren对应的List。最后的成果(css不在这里给出)
[img]http://dl2.iteye.com/upload/attachment/0115/3602/caf589ab-5513-30d4-bb18-6dd79cc4f46a.png[/img]
解决这类不清楚有多少级节点的问题,用递归是最清爽的一个办法。
页面上最后展现的形式
<ul>
<li><div>一级节点</div>
<ul>
<li><div>二级节点</div>
<ul>
<li><div>三级节点</div></li>
</ul>
</li>
<li><div>二级节点</div></li>
</ul>
整理一下逻辑:前台需要的是一个List<HashMap>,list里每一个对象应该有一个key = "children" 对应的value 是List<HashMap>(子级节点数组),同理每一个子集节点还要有key="children"对应List<HashMap>,这样就形成了递归;
java后台:
首先根据我的一张组织架构的表如下
[img]http://dl2.iteye.com/upload/attachment/0115/3582/a65b5eb8-ca57-306f-9f7f-377e728d1be3.png[/img]
我们只需要关心 department_id 和 department_parent_id。
先把所有的department查询出来组成一个List<HashMap>,
下面我写了一个递归把没有层级结构的的List<HashMap>转化成前台需要的List<HashMap>
package com.asclepius.slhdt.uim.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
public class TreeUtil {
/**
* @param dataSource list数据源
* @param id 层级结构id
* @param parentId 父级节点id
* @return
*/
public static LinkedHashMap<String,HashMap> getTreeData(List<HashMap> dataSource,String id,String parentId)
{
LinkedHashMap returnMap = new LinkedHashMap();
HashMap<String,String> root = new HashMap<String,String>();
root.put(id, "");
assembleTree(dataSource,root,id,parentId,1);
returnMap.put("root",root);
return returnMap;
}
public static void assembleTree(List<HashMap> dataSource,HashMap node ,String id,String parentId,Integer level)
{
List childList = getChildList(dataSource,node,id,parentId);
node.put("children", childList);
if(childList.size() > 0)
{
for(int i = 0 ; i<childList.size(); i++ )
{
HashMap child = (HashMap)childList.get(i);
child.put("level", level);
assembleTree(dataSource,child,id,parentId,level+1);
}
}
}
/**
* 得到子节点列表
*/
private static List getChildList(List<HashMap> dataSource,HashMap node,String id, String parentId )
{
List childList = new ArrayList();
for (int i = 0; i < dataSource.size() ; i++)
{
HashMap child = (HashMap)dataSource.get(i);
String dictId = node.get(id).toString();
String dictParentId = child.get(parentId).toString();
if (dictId.equals(dictParentId))
{
childList.add(child);
dataSource.remove(i);
i--;
}
}
return childList;
}
}
返回给页面
LinkedHashMap<String,HashMap> hierarchyList = TreeUtil.getTreeData(departmentList,"departmentId","departmentParentId");
List tree = (List)(hierarchyList.get("root").get("children"));
return tree;
//组织架构树
$.ajax({
url:"/department/getdepartmentTree",
type:"get",
data:{hospitalId:hospital_id},
success:function(data)
{
$(".subdivision").append(assembleTopTree(data));
}
});
/**
* 组装一级节点
*/
function assembleTopTree(deptList)
{
var $ul = $("<ul class='department-stair' id='deptTree' style='display:none' />");
for(var i = 0; i<deptList.length; i++)
{
var $li=$("<li data-dept-id=" + deptList[i].departmentId + " >" +
"<div class='department-name stair' >" +
imgClick(deptList[i],true) +
"</div>"+
"<div class='subdivision-operate clearfix'>" +
"<a href='javascript:void(0)' class='adddept' data-dept-id="+deptList[i].departmentId + ">添加子部门</a>" +
"<a href='javascript:void(0)' class='editdept' data-dept-id="+ deptList[i].departmentId + " >编辑</a><span>|</span>"+
"<img class='delete' src='../../images/department/delete.png' data-dept-id="+ deptList[i].departmentId + " alt='删除' title='删除'/>" +
mouseUpClass(i,deptList) + mouseDownClass(i,deptList) +
"</div>" + assembleChildrenTree(deptList[i].children , deptList[i].departmentId)+"</li>");
$ul.append($li);
}
return $ul;
}
/**
* 组装子级节点
*/
function assembleChildrenTree(deptList,departmentId)
{
var $ul = $("<ul class='department-stair' style='display:none' id="+ departmentId +"/>");
for(var i = 0; i<deptList.length; i++)
{
var $li=$("<li data-dept-id=" + deptList[i].departmentId + " >" +
"<div class='department-name stair' >" +
imgClick(deptList[i],false) +
"</div>"+
"<div class='subdivision-operate clearfix'>" +
"<a href='javascript:void(0)' class='adddept' data-dept-id="+deptList[i].departmentId + ">添加子部门</a>" +
"<a href='javascript:void(0)' class='editdept' data-dept-id="+ deptList[i].departmentId + " >编辑</a><span>|</span>"+
"<img class='delete' src='../../images/department/delete.png' data-dept-id="+ deptList[i].departmentId + " alt='删除' title='删除'/>" +
mouseUpClass(i,deptList) + mouseDownClass(i,deptList) +
"</div>" + assembleChildrenTree(deptList[i].children,deptList[i].departmentId) + "</li>");
$ul.append($li);
}
return $ul[0].outerHTML;
}
/**
* 是否有鼠标经过class
*/
function mouseUpClass(index , list)
{
if(index == 0)
return "<img class='move-up' style='opacity:0.4' src='../../images/department/move_up.png' alt=''/>";
else
return "<img class='move-up' src='../../images/department/move_up.png' alt=''/>";
}
/**
* 是否有鼠标经过class
*/
function mouseDownClass(index , list)
{
if(index == list.length - 1)
return "<img class='move-down' style='opacity:0.4' src='../../images/department/move_down.png' alt=''/>";
else
return "<img class='move-down' src='../../images/department/move_down.png' alt=''/>";
}
/**
* 是否有展开按钮图标
*/
function imgClick(item , topOrChild)
{
if(topOrChild)
if(item.children.length > 0)
return "<img src='../../images/department/arrow_right.png' data-dept-id="+item.departmentId +" style='margin-left:"+ item.level*10 +"px' /><span>"+ item.departmentProp.departmentNameAlias +"</span>"+
(item.departmentProp.departmentClinical == 1 ? "<span class='identifier'>临床</span>" : "");
else
return "<span style='margin-left:"+ (14 + item.level*10) +"px' >"+ item.departmentProp.departmentNameAlias +"</span>"+
(item.departmentProp.departmentClinical == 1 ? "<span class='identifier'>临床</span>" : "");
else
if(item.children.length > 0)
return "<img src='../../images/department/arrow_right.png' data-dept-id="+item.departmentId +" style='margin-left:"+ item.level*10 +"px' /><span>"+ item.departmentProp.departmentNameAlias+"</span>"
+(item.departmentProp.departmentClinical == 1 ? "<span class='identifier'>临床</span>" : "");
else
return "<span style='margin-left:"+ (14 + item.level*10) +"px' >"+ item.departmentProp.departmentNameAlias +"</span>" +
(item.departmentProp.departmentClinical == 1 ? "<span class='identifier'>临床</span>" : "");
}
assembleChildrenTree中判断如果children长度不为0,再次调用assembleChildrenTree传入chidlren对应的List。最后的成果(css不在这里给出)
[img]http://dl2.iteye.com/upload/attachment/0115/3602/caf589ab-5513-30d4-bb18-6dd79cc4f46a.png[/img]