前言
有空研究了一下Layui,感觉相对于EasyUI来说,美观了不少,结合后台加载动态Tree带大家初步了解一下这个框架
实现步骤
初步准备
Layui官网
去官网下载好Layui,里面有示例和css、js等文件
具体使用步骤:
要使用Layui,必须引入css文件和js文件:
<link rel="stylesheet" href="css/layui.css" />
Layui官方文档是说有两种加载方式的,也就是:非模块化方式和模块化方式
两者区别就是:
非模块化方式所有模块一次性加载,而模块化方式加载指定的模块:例如引用tree的模块…
<script>
layui.use('tree', function(){});
</script>
有一点注意:官方说的是使用非模块化方式加载引入的是layui.all.js
文件,但是使用模块化加载时,引入layui.all.js
才有样式效果,具体原因不太清楚(layui官方对tree组件可能做了更新,但是具体的更新日至稳定没见着)
构建data数据源
一起来看官方文档中对Tree组件的结构要求和参数介绍:
为了追求简单实现效果,就不弄花里胡哨的了,直接拿最主要的属性:
<script>
//由于模块都一次性加载,因此不用执行 layui.use() 来加载对应模块,直接使用即可:
;
! function() {
var layer = layui.layer,
form = layui.form,
tree = layui.tree;
//渲染
tree.render({
elem: '#test1' //绑定元素
,
data: [//后台传入指定格式json对象数组]
});
}();
</script>
后台构建对应节点:
TreeVo节点实体类:
package com.xiaoyang.vo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class TreeVo<T> {
/**
* 节点ID索引
*/
private String id;
/**
* 显示节点标题
*/
private String title;
/**
* 节点的子节点
*/
private List<TreeVo<T>> children = new ArrayList<TreeVo<T>>();
/**
* 父ID
*/
private String parentId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<TreeVo<T>> getChildren() {
return children;
}
public void setChildren(List<TreeVo<T>> children) {
this.children = children;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public TreeVo(String id, String title, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
List<TreeVo<T>> children, boolean isParent, boolean isChildren, String parentID) {
super();
this.id = id;
this.title = title;
this.children = children;
this.parentId = parentID;
}
public TreeVo() {
super();
}
}
这里比较奇怪一点就是,明明官方文档写的指定数据源格式没有parentId
等选项,我构建和EasyUI一样的数据源都能ok,感觉layui的文档完整性不太好…
BuildTree构建节点结构方法类:
package com.xiaoyang.util;
import com.xiaoyang.vo.TreeVo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BuildTree {
/**
* 指定idparam为顶级节点
* @param nodes
* @param idParam
* @param <T>
* @return
*/
public static <T> List<TreeVo<T>> buildList(List<TreeVo<T>> nodes, String idParam) {
if (nodes == null) {
return null;
}
List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();
for (TreeVo<T> children : nodes) {
String pid = children.getParentId();
if (pid == null || idParam.equals(pid)) {
topNodes.add(children);
continue;
}
for (TreeVo<T> parent : nodes) {
String id = parent.getId();
if (id != null && id.equals(pid)) {
parent.getChildren().add(children);
continue;
}
}
}
return topNodes;
}
}
后台方法构建好后,只需将数据源进行Json解析后,进行后台获取输出到页面即可:
/**
* 封装节点方法
* @param menu
* @param pageBean
* @return
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public List<TreeVo<Permission>> topNode(Permission permission,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException{
List<Permission> list = this.list(permission, pageBean);
List<TreeVo<Permission>> nodes = new ArrayList<TreeVo<Permission>>();
TreeVo treevo = null;
for (Permission m : list) {
treevo = new TreeVo<>();
treevo.setId(m.getId()+"");//设置节点id
treevo.setTitle(m.getName()+"");//设置节点文本
treevo.setParentId(m.getPid()+"");//设置父节点
nodes.add(treevo);
}
return BuildTree.buildList(nodes,"0");//返回构建好的节点树结构
}
/**
* 对传入节点进行Json解析,并输出到页面
* @param response
* @param o
* @throws Exception
*/
public static void writeJson(HttpServletResponse response,Object o)throws Exception{
response.setContentType("text/html;charset=utf-8");
ObjectMapper om=new ObjectMapper();
String jsonStr = om.writeValueAsString(o);
PrintWriter out=response.getWriter();
System.out.println(jsonStr.toString());
out.println(jsonStr.toString());
out.flush();
out.close();
}
到这里,后台已经搞定,重要的部分来了:由于官方文档并没有看到Tree结构后台动态加载,也没有提供类似于url
的跳转路径参数,所以博主结合ajax
跳转后台获取数据源:
//由于模块都一次性加载,因此不用执行 layui.use() 来加载对应模块,直接使用即可:
;
!function() {
var id = "";
var atitle = "";
var layer = layui.layer, form = layui.form, tree = layui.tree, element = layui.element;
// 渲染
tree.render({
elem : '#test1' // 绑定元素
,
data :eval('(' + getData() + ')'),
});
}();
function getData(){
var ctx=$("#ctx").val();
var data ;
$.ajax({
url:ctx+"/permission.action?opt=PermissionTree",
type:"post",
async:false,
success:function(result){
data=result;
}
});
return data;
}
这里一定要注意一点:一定要将获取到的数据源进行eval()
函数的转换,否则所有节点都是未定义,
取到的getData()是一个字符串而不是一个对象,所以下面取不到对象的属性,类似于:
<script>
var jsonData = [{
"id": "1",
"title": "书籍管理",
"state": null,
"checked": false,
"attributes": null,
"children": [],
"parentId": "0",
"hasParent": false,
"hasChildren": false
}];
console.log(jsonData.id);
</script>
undefined
数据库表结构:
最后附上效果图: