基于layui的树结构表格开源插件:https://gitee.com/whvse/treetable-lay/
我的种类表是有pid的父子结构。
cg_id是主键,cg_parent是代表父分类pid
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: []
}]
}];
该插件有两种方法请求数据,一种是固定数组,一种是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 ()
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,获取到数据第一步始终转换成嵌套的父子结构。内部处理的各种逻辑都需要基于这个嵌套结构。
另外:由于我没有 haveChild 这个字段判断有没子级,在更改下拉图标时,需要判断转换后的嵌套父子结构。判断他的children有没值。d.children && d.children.length > 0
if (d.children && d.children.length > 0) { // 判断是否有子集
return '';
} else {
return '';
}
//整个初始化
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 '';
} else {
return '';
}
}
},
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);
});
}
});