目录
zTree是一个用来做树形结构的插件
通过从数据库获得的数据显示树形图
1、后端
1.1 树形结构的实体类
数据库字段
public class Menu {
//主键
private Integer id;
//对应父节点pid,如果pid为null,它就是根节点
private Integer pid;
//节点名称
private String name;
//节点对应的url地址
private String url;
//节点的图标
private String icon;
//当前节点的子节点集合,设置默认值是避免组装节点时空指针异常
private List<Menu> children=new ArrayList<>();
//控制节点展开还是折叠,true是展开
private Boolean open=true;
}
1.2 json请求响应格式的实体类
public class ResultEntity<T> {
public static final String SUCCESS = "SUCCESS";
public static final String FAILED = "FAILED";
public static final String NO_MESSAGE = "NO_MESSAGE";
public static final String NO_DATA = "NO_DATA";
// 方便返回成功结果(不携带查询结果情况)
public static ResultEntity<String> successWithoutData() {
return new ResultEntity<String>(SUCCESS, NO_MESSAGE, NO_DATA);
}
// 方便返回成功结果(携带查询结果情况)
public static <E> ResultEntity<E> successWithData(E data) {
return new ResultEntity<E>(SUCCESS, NO_MESSAGE, data);
}
// 方便返回失败结果
public static <E> ResultEntity<E> failed(E data, String message) {
return new ResultEntity<E>(FAILED, message, data);
}
private String result;
private String message;
private T data;
}
1.3 controller类
//让他们找到各自的父节点
@RequestMapping("/menu/get/whole/tree")
public ResultEntity<Menu> getWholeTree() {
// 1 查询所有的属性节点用于组装
List<Menu> menuList = menuService.getAll();
// 2、将List<Menu>转为Map<Menu的id,Menu>
Map<Integer, Menu> menuMap = new HashMap<>();
for (Menu menu : menuList) {
Integer id = menu.getId();
menuMap.put(id, menu);
}
//3、 声明变量用于存储根节点对象
Menu rootNode = null;
//4、遍历List<Menu>
for (Menu menu : menuList) {
// 5 获取当前Menu对象的pid属性
Integer pid = menu.getPid();
// 6 判断pid是不是Null
if (pid == null) {
// 7 pid为空,说明这个对象是根节点,所以赋值给根节点对象
rootNode = menu;
// 8 根节点没有父节点,所以不必找父节点,停止本次循环,继续执行下一次循环
continue;
}
//9 不为null,根据pid查找当前节点的父节点
Menu menu2=menuMap.get(pid);
menu2.getChildren().add(menu);
}
return ResultEntity.successWithData(rootNode);
}
2、前端
下载ztree
2.1 引入需要的js
<script src="jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>
2.2 jsp代码
<SCRIPT type="text/javascript">
$(document).ready(function() {
//setting对象中包含zTree的设置属性
var setting = {
//改图标
"view" : {
"addDiyDom" : showMyIcon
},
//url设置不存在的路径,就不会跳转,如果存在,就可以点击跳转
"data":{
"key":{
"url":"sdsadsa"
}
}
};
//发送ajax请求拿到zNode数据
$.ajax({
"url" : "menu/get/whole/tree.json",
"type" : "post",
"dateType" : "json",
"success" : function(response) {
var result = response.result;
if (result == "SUCCESS") {
//用于显示树形结构的节点数据
var zNodes = response.data;
console.log(zNodes);
//执行树形结构的初始化操作
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
}
if (result == "FAILED") {
layer.mag("加载数据菜单失败:" + response.message);
}
},
"error" : function(response) {
layer.mag("加载数据菜单失败:" + response.message);
}
})
});
//由setting.view.adDiyDom属性引用,负责显示自定义图标
//treeId是<ul id="treeDemo" class="ztree"></ul>的id值
//treeNode对应每一个树形节点
function showMyIcon(treeId, treeNode) {
//获取当前节点的id
var currentNodeId=treeNode.tId;
//获取新的class值用于替换
var newClass=treeNode.icon;
//将当前节点id之后附加“_ico”得到目标span的id
var targetSpanId=currentNodeId+"_ico";
//将目标的span的旧class移除,添加新class
$("#"+targetSpanId).removeClass().addClass(newClass).css("background","");
}
</SCRIPT>
树形图显示的位置
<div class="panel-body">
<ul id="treeDemo" class="ztree"></ul>
</div>
3、标准JSON数据的zTree
以上的示例就是一个标准JSON数据的zTree,返回的JSON值需要如下所示:
标准的 JSON 数据需要嵌套表示节点的父子包含关系
例如:
var zNodes =[
{ name:"父节点1 - 展开", open:true,
children: [
{ name:"父节点11 - 折叠",
children: [
{ name:"叶子节点111"},
{ name:"叶子节点112"},
{ name:"叶子节点113"},
{ name:"叶子节点114"}
]},
{ name:"父节点12 - 折叠",
children: [
{ name:"叶子节点121"},
{ name:"叶子节点122"},
{ name:"叶子节点123"},
{ name:"叶子节点124"}
]},
{ name:"父节点13 - 没有子节点", isParent:true}
]},
{ name:"父节点2 - 折叠",
children: [
{ name:"父节点21 - 展开", open:true,
children: [
{ name:"叶子节点211"},
{ name:"叶子节点212"},
{ name:"叶子节点213"},
{ name:"叶子节点214"}
]},
{ name:"父节点22 - 折叠",
children: [
{ name:"叶子节点221"},
{ name:"叶子节点222"},
{ name:"叶子节点223"},
{ name:"叶子节点224"}
]},
{ name:"父节点23 - 折叠",
children: [
{ name:"叶子节点231"},
{ name:"叶子节点232"},
{ name:"叶子节点233"},
{ name:"叶子节点234"}
]}
]},
{ name:"父节点3 - 没有子节点", isParent:true}
];
从数据格式来看,实体类就得有一个List来装它的子类,而它的子类就是这个子节点,返回JSON格式数据的时候需要封装一下,具体封装查看1.3Controller。
4、简单JSON数据的zTree
- 启用简单JSON功能
setting.data.simpleData.enable设置为true
- 设置显示节点名称的实体类属性名
setting.data.key.name设置为title
- 设置当前节点父节点的属性名
setting.data.simpleData.pIdKey设置为categoryId
- 展开整个树形结构
$.fn.zTree.getZTreeObj("treeDemo").expandAll(true);
- 设置树形节点前显示checkbox
setting.check.enable设置为true
例如:
简单模式的 JSON 数据需要使用 id / pId 表示节点的父子包含关系,如使用其他属性设置父子关联关系请参考 setting.data.simple 内各项说明
例如:
var nodes = [
{id:1, pId:0, name: "父节点1"},
{id:11, pId:1, name: "子节点1"},
{id:12, pId:1, name: "子节点2"}
];
简单的JSON数据就没有标准的JSON数据麻烦,只需要这个属性有一个pid来指定它的父节点,zTree就能显示
4.1 查询所有数据
//使用Map而不是多重循环,改进了时间复杂度,让它的运行次数变少了,简单JSON格式的zTree的格式
@RequestMapping("/menu/get/whole/tree")
public ResultEntity<List<Menu>> getWholeTree() {
// 1 查询所有的属性节点用于组装
List<Menu> menuList = menuService.getAll();
return ResultEntity.successWithData(menuList);
}
4.2 zTree设置
设置ztree
var setting = {
"view" : {
"addDiyDom" : showMyIcon,
"addHoverDom": addHoverDom,
"removeHoverDom": removeHoverDom
},
"data" : {
"key" : {
"url" : "sdsadsa"
},
"simpleData": {
//开启简单json格式
"enable": true,
//父类属性的名称
"pIdKey": "pid"
}
}
};