上篇博客中,其实就是异步加载,只不过是一次性从后台把数据都获取出来。当数据量超大时,一次性加载,可能出现性能问题。因此我们可以采用另一种方式,也就是网上人们所说的异步加载。
为了和上篇博客中的资料进行区分,我把他称为“逐步异步加载”!哈哈,够形象吧。本质就是,初始化tree时,只显示根节点,当点击某一节点时,就要把该节点的id传到后台,并获取该节点下一级的所有节点信息,然后展开该节点。
由于每次只是返回部分数据,无法自动判断是否为子节点,然后进行样式区分。因此得需要自己手动配置每个节点的属性,也就是isParent属性。
先来看一下我们Manager层的方法。
/*
* 异步逐步加载所有的部门及用户
*/
public List getPartTree(String pId) {
String hql = "SELECT"
+ " d.id AS id ,d.departName AS `name`,d.parentId AS pId,true AS isDep,'' AS icon,((SELECT count(u1.id) from imuser AS u1 WHERE u1.departId=d.id)+(SELECT count(p.id) FROM imdepart AS p WHERE p.parentId=d.id)) AS isParent"
+ " FROM"
+ " imdepart AS d"
+ " WHERE"
+ " d.parentId = " + pId
+ " UNION"
+ " SELECT"
+ " u.id AS id,u.`name` AS `name`,u.departId AS pId,false AS isDep,'/mvn1/img/tree/portrait.png' AS icon,false AS isParent"
+ " FROM"
+ " imuser AS u"
+ " WHERE"
+ " u.departId = " + pId;
List list = dao.queryBySql(hql);
return list;
}
这里需要解决一下:
- 我们这次显示是把部门和用户放在一起了,也就是上面看到的“UNION”。
- 可以看到每个字段都加上了别名,就是为了好认。
- 因为部门和用户是来自于两张表,主键id可能相同,我们加了“isDep”列,进行区分。
- 由于部门和用户的图标不一样,我们加了icon一列,对于用户,我们给予新的用户图标。
- 还有一点,就是上面所说的“isParent”属性了。
下面就是我们Action中的方法了。
/*
* 异步逐步加载部门及用户
*/
public String listPartByAjax() throws Exception {
// 用于异步树的逐步加载
String pId=ServletActionContext.getRequest().getParameter("pId");
System.out.println(pId);
if (null==pId || "".equals(pId)) {
pId="0";
}
List<Tree> listTree = new ArrayList<Tree>();
List list = departmentManager.getPartTree(pId);
for (int i = 0; i < list.size(); i++) {
Tree tree = new Tree();
// objects为数组,依次为:id,name,pId,isDep,icon,isParent
Object[] objects = (Object[]) list.get(i);
tree.setId(Integer.valueOf(objects[0].toString())); // id
tree.setName(objects[1].toString()); // 名称
tree.setpId(Integer.valueOf(objects[2].toString())); // 父Id或部门Id,在此都统一为pId
tree.setIsDep(Integer.valueOf(objects[3].toString())); // 是否为部门
tree.setIcon(objects[4].toString()); // 是否有自己的图标(用户有自己的图标)
tree.setIsParent(Integer.valueOf(objects[5].toString())); // 是否是父节点,以用于图标显示
listTree.add(tree);
}
JSONArray json = JSONArray.fromObject(listTree);
renderText(json.toString());
return null;
}
由于返回的是List集合,每个元素又是一个数组,我们需要获取到每个数据,赋值给我们的List<Tree>。最后转成Json字符串,传给前台页面。
再点看一下我们的前台代码:
$(function() {
var setting = {
view : {
dblClickExpand : false,
selectedMulti : false
},
async : {
enable : true,
url : "test!listPartByAjax.action",
autoParam : [ "id=pId" ]
}
};
$.fn.zTree.init($("#tree"), setting);
});
由于每个节点的属性,后台都赋好了值,上篇看到的“data”配置已不在了。我们看到“autoParam : [ "id=pId" ]”,就是每次点击节点,把pId值赋给id,并传给后台。原以为这种异步加载得多么复杂了,可以看出配置参数反而更简单了。
最后看一下效果图: