Layui实现动态加载Tree

目录

    • 前言
    • 实现步骤
      • 初步准备
      • 构建data数据源

前言

有空研究了一下Layui,感觉相对于EasyUI来说,美观了不少,结合后台加载动态Tree带大家初步了解一下这个框架

实现步骤

初步准备

Layui官网
去官网下载好Layui,里面有示例和css、js等文件
在这里插入图片描述
具体使用步骤:
要使用Layui,必须引入css文件和js文件:

1
<link rel="stylesheet" href="css/layui.css" />

在这里插入图片描述
Layui官方文档是说有两种加载方式的,也就是:非模块化方式和模块化方式
两者区别就是:
非模块化方式所有模块一次性加载,而模块化方式加载指定的模块:例如引用tree的模块…

1
2
3
<script>
layui.use('tree', function(){});
</script>

有一点注意:官方说的是使用非模块化方式加载引入的是layui.all.js文件,但是使用模块化加载时,引入layui.all.js才有样式效果,具体原因不太清楚(layui官方对tree组件可能做了更新,但是具体的更新日至稳定没见着)

构建data数据源

一起来看官方文档中对Tree组件的结构要求和参数介绍:
在这里插入图片描述在这里插入图片描述为了追求简单实现效果,就不弄花里胡哨的了,直接拿最主要的属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        <script>
            //由于模块都一次性加载,因此不用执行 layui.use() 来加载对应模块,直接使用即可:
            ;
            ! function() {
                var layer = layui.layer,
                    form = layui.form,
                    tree = layui.tree;
                    //渲染
                    tree.render({
                        elem: '#test1' //绑定元素
                            ,
                        data: [//后台传入指定格式json对象数组]
                    });
            }();
        </script>

后台构建对应节点:
在这里插入图片描述TreeVo节点实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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构建节点结构方法类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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解析后,进行后台获取输出到页面即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
       /**
         * 封装节点方法
         * @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");//返回构建好的节点树结构
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   /**
     * 对传入节点进行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跳转后台获取数据源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//由于模块都一次性加载,因此不用执行 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()是一个字符串而不是一个对象,所以下面取不到对象的属性,类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
         <script>
                var jsonData = [{
                    "id": "1",
                    "title": "书籍管理",
                    "state": null,
                    "checked": false,
                    "attributes": null,
                    "children": [],
                    "parentId": "0",
                    "hasParent": false,
                    "hasChildren": false
                }];
               console.log(jsonData.id);
        </script>

1
undefined

数据库表结构:
在这里插入图片描述
最后附上效果图:
在这里插入图片描述