treeTable树结构表格的使用

基于layui的树结构表格开源插件:https://gitee.com/whvse/treetable-lay/

我的种类表是有pid的父子结构。

cg_id是主键,cg_parent是代表父分类pid

1、首先把表格绑定到一个dom

<table id="demoTb1"></table>

2、引入treeTable插件

    layui.config({
        base: '/backend/module/'
    }).extend({
        treeTable:'treetable/treeTable'
    }).use(['treeTable'], function () {
        var treeTable = layui.treeTable;
        //初始化渲染表格
    });
这是插件处理的数据结构,是个数组。两种数组结构,一种是基于pid形式的父子结构,另一种是内置嵌套的父子结构。

第一种:pid形式的父子结构(这个在数据库中可以自连接)

var data = [{
    id: '1',
    name: 'xxx',
    createTime: '2019/11/18 10:44:00',
}, {
    pid: '1',
    id: '1_1',
    name: 'xxx',
    createTime: '2019/11/18 10:44:00'
},{
    id: '2',
    name: 'xxx',
    createTime: '2019/11/18 10:44:00',
},{
    pid: '2',
    id: '2_1',
    name: 'xxx',
    state: 0,
    createTime: '2019/11/18 10:44:00',
    children: []
}];

 第二种:内置嵌套的父子结构,(这个子结构嵌套在父结构属性中)

var data = [{
            id: '1',
            name: 'xxx',
            createTime: '2019/11/18 10:44:00',
            children: [ {
                id: '1_1',
                name: 'xxx',
                createTime: '2019/11/18 10:44:00'
            }]
        }, {
            id: '2',
            name: 'xxx',
            createTime: '2019/11/18 10:44:00',
            children: [{
                id: '2_1',
                name: 'xxx',
                state: 0,
                createTime: '2019/11/18 10:44:00',
                children: []
            }]
        }];

3、获取数据渲染表格

该插件有两种方法请求数据,一种是固定数组,一种是ajax异步请求json

第一种:就是上述结构数组。使用data:属性配置。(elem选择绑定dom的id)

// 渲染表格
var insTb = treeTable.render({
    elem: '#demoTb1',
    data: data,  // 数据
    tree: {
        iconIndex: 1,  // 折叠图标显示在第几列
        isPidData: true  // 是否是pid形式数据
    },
    cols: [
        {type: 'numbers'},
        {field: 'id', title: 'ID'},
        {field: 'name', title: 'name', width: 160},
        {field: 'createTime', title: '创建时间', width: 180}
    ]
});

第二种:使用内置方法,使用reqData:方法内异步获取json,回调结果。

var insTb = treeTable.render({
    elem: '#demoTb1',
    tree: {
        iconIndex: 1,  // 折叠图标显示在第几列
        idName: 'id',  // 自定义id字段的名称
        pidName: 'pid',  // 自定义标识是否还有子节点的字段名称
        haveChildName: 'haveChild',  // 自定义标识是否还有子节点的字段名称
        isPidData: true  // 是否是pid形式数据
    },
    cols: [
        {type: 'numbers'},
        {field: 'id', title: 'ID'},
        {field: 'name', title: 'name', width: 160},
        {field: 'createTime', title: '创建时间', width: 180}
    ],
    reqData: function(data, callback) {
        // 在这里写ajax请求,通过callback方法回调数据
        $.get('list.json', function (res) {
            callback(res.data);  // 参数是数组类型
        });
    }
});

两种方法,如果异步加载json,data属性不填,填了固定data数组,reqData就不写。

—————————————————————————————————————————————————

OK,基本关键讲完了使用方法,其他参数使用看文档。现在记录下我使用中遇到的问题。

由于数据库固定了。所以就按照pid形式的父子结构做。结果无法加载出来。

报错大概意思是栈溢出了。

Uncaught RangeError: Maximum call stack size exceeded
    at String.slice (<anonymous>)
    at isClass (treeTable.js:1382)
    at pidEquals (treeTable.js:1364)
    at Object.pidToChildren (treeTable.js:1406)
    at Object.pidToChildren (treeTable.js:1407)
    at Object.pidToChildren (treeTable.js:1407)
    at Object.pidToChildren (treeTable.js:1407)
    at Object.pidToChildren (treeTable.js:1407)
    at Object.pidToChildren (treeTable.js:1407)
    at Object.pidToChildren (treeTable.js:1407)

控制台打印出来,我获取到的数据。

Array(9)
0: {cgId: 0, cgParent: 0, cgName: "全部分类", cgStatus: "1"}
1: {cgId: 1, cgParent: 0, cgName: "个人电脑", cgStatus: "1"}
2: {cgId: 2, cgParent: 0, cgName: "移动设备", cgStatus: "1"}
3: {cgId: 3, cgParent: 0, cgName: "摄影摄像", cgStatus: "1"}
4: {cgId: 4, cgParent: 0, cgName: "娱乐设备", cgStatus: "1"}
5: {cgId: 5, cgParent: 0, cgName: "影音TV", cgStatus: "1"}
6: {cgId: 6, cgParent: 0, cgName: "外设和其他", cgStatus: "1"}
7: {cgId: 7, cgParent: 1, cgName: "笔记本电脑", cgStatus: "1"}
8: {cgId: 8, cgParent: 1, cgName: "桌面电脑", cgStatus: "1"}
length: 9
__proto__: Array(0)

我看了下插件的代码,发现无论是固定数组还是异步获取的json,获取到数据第一步始终转换成嵌套的父子结构。内部处理的各种逻辑都需要基于这个嵌套结构。 

找到了原因:原本我是想把0当做父根目录的,根0的父级pid也是0,所以for就死循环出不来,栈就挤满爆炸了。

解决方法:把根父类的父类pid改成-1。

另外:由于我没有 haveChild 这个字段判断有没子级,在更改下拉图标时,需要判断转换后的嵌套父子结构。判断他的children有没值。d.children && d.children.length > 0

if (d.children && d.children.length > 0) {  // 判断是否有子集
                    return '<i class="ew-tree-icon ew-tree-icon-folder"></i>';
                } else {
                    return '<i class="ew-tree-icon ew-tree-icon-file"></i>';
                }

//整个初始化
var insTb = treeTable.render({
        elem: '#demoTb1',
        tree: {
            iconIndex: 2,  // 折叠图标显示在第几列
            idName: 'cgId',  // 自定义id字段的名称
            pidName: 'cgParent',  // 自定义标识是否还有子节点的字段名称
            // haveChildName: 'haveChild',  // 自定义标识是否还有子节点的字段名称
            isPidData: true,  // 是否是pid形式数据
            arrowType: 'arrow2',   // 自定义箭头风格
            getIcon: function(d) {  // 自定义图标
                console.log(d);
                // d是当前行的数据
                if (d.children && d.children.length > 0) {  // 判断是否有子集
                    return '<i class="ew-tree-icon ew-tree-icon-folder"></i>';
                } else {
                    return '<i class="ew-tree-icon ew-tree-icon-file"></i>';
                }
            }
        },
        cols: [
            {type: 'checkbox',width: 30},
            {type: 'numbers',title: '序号',width: 30},
            {field: 'cgName', title: '类名', width: 160},
            {field: 'cgId', title: '自ID',width: 100},
            {field: 'cgParent', title: '父ID', width: 100},
            {field: 'cgStatus', title: '状态', width: 80,templet:'#statusTpl'},
            {field: 'cgStatus', title: '操作', width: 100,templet:'#barDemo'}
        ],
        reqData: function(data, callback) {
            $.get('/backend/category/items', function (res) {
                var resData = res.datas;
                console.log(resData);
                callback(resData);
            });
        }
    });

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值