最近在使用ztree时,发现还是有很多没有彻底弄明白的地方。
1、比如成树结构的条件是什么?
2、到底是使用扁平数据结构还是树数据结构?
咱们来一个一个解决。
一、ztree成树的关键条件是什么?
1、首先,这个问题分两部分,如果是扁平数据结构时,则关键属性就是isParent(true) pid属性。 配置如下:
var treeSetting = {
view: {
showLine: false,
showIcon: true, //可以配置上true,显示前面自定义的小三角
selectedMulti: false,
expandSpeed: 'fast'
},
//这里注释掉,ztree单选时这里不需要配置,多选时才需要配置。
/* check: {
enable: true,
chkboxType: { Y: 'ps', N: 'ps' },
chkStyle: 'radio'
}, */
data: {
simpleData: {
enable: false //按照嵌套数据结构显示,下面的idKey;pIdkey和rootPId属性时扁平数据结构时需要配置的。
// idKey: 'id',
// pIdKey: 'pid',
// rootPId: 0
},
key: {
name: 'name',
children: 'childList' //这里ztree默认的是children,这个可以看ztree的官网,配置成childList,则表明嵌套型数据结构是用childList代替children的
},
keep: {
leaf: true
}
},
callback: {
onClick: function (event, treeId, treeNode) {
if (treeNode.hasChildren) {
ufma.showTip('请选择最末级节点进行查询')
} else {
semanticTreeSelected = treeNode
page.getSemanticModel(treeNode.id, function (treeData) {
$('#semanticTable_wrapper').ufScrollBar('destroy')
page.tableObj.clear().destroy()
$('#semanticTable').empty()
page.initTable('semanticTable', treeData.tree)
})
}
},
onDblClick: function () {},
onAsyncSuccess: function () {}
}
}
最近在查阅文档时发现,ztree成树的关键条件就是isParent属性。因为我在做需求时,发现接口是点节点调用接口返回下一级节点,此时数据结构上是没有isParent属性的,只有一个hasChildren为true,但是界面上我是想让折叠的小三角显示的,因此,我就在获取父级节点后,如果hasChildren为true,则前端给其增加属性isParent=true,这样前面的折叠小三角就会出现。代码如下:
for (let i = 0; i < data.length; i++) {
data[i].codeName = data[i].multiLangName.zh_CN
data[i].pId = treeNode.id
// 这里给节点数据增加isParent=true的属性,以让父节点前面显示折叠小三角,而且这里的ztree的树结构要靠前端组装
if (data[i].hasChildren) {
data[i].isParent = true
data[i].open = false
}
if (level2Data.length) {
if (level2Data.findIndex(item => item.id === data[i].id) === -1) {
level2Data.push(data[i])
}
} else {
level2Data.push(data[i])
}
}
但是后来越做越发现,这样的交互效果不好。需要用户一级一级的点击才能获取到完整的树节点,而且有一个致命的问题是,当我点击开某一个节点的全部节点后,因为树数据会重新组装,则树组件会重新渲染,然后我打开的某一个节点的全部子节点又恢复到全部折叠的状态了。这样用户体验也太差了,后来跟后端又沟通了下,他直接给出了全部的树节点,是嵌套数据结构的。最后在此记录一下,如果遇到这种情况,前端还是要坚持自己的态度,该后端提供的就一定让他们提供,不要自己默默的做。
最后后端给的数据结构是这样的:
[
{
id:'01'
pid:'root',
hasChildren:false,
name:'父节点',
childList:[
{
id:'0101'
pid:'01',
hasChildren:false,
name:'子节点1',
},
{
id:'0102'
pid:'01',
hasChildren:false,
name:'子节点2',
}
]
}
]
这样ztree的配置如下:
var treeSetting = {
view: {
showLine: false,
showIcon: true, //可以配置上true,显示前面自定义的小三角
selectedMulti: false,
expandSpeed: 'fast'
},
data: {
simpleData: {
enable: false //按照嵌套数据结构显示,为true时,则是按照扁平结构显示树结构
},
key: {
name: 'name',
children: 'childList' //这里ztree默认的是children,这个可以看ztree的官网,配置成childList,则表明嵌套型数据结构是用childList代替children的
},
keep: {
leaf: true
}
},
callback: {
onClick: function (event, treeId, treeNode) {
if (treeNode.hasChildren) {
ufma.showTip('请选择最末级节点进行查询')
} else {
semanticTreeSelected = treeNode
page.getSemanticModel(treeNode.id, function (treeData) {
$('#semanticTable_wrapper').ufScrollBar('destroy')
page.tableObj.clear().destroy()
$('#semanticTable').empty()
page.initTable('semanticTable', treeData.tree)
})
}
},
}
}
二、到底是使用扁平数据结构还是树数据结构?
那就要看后端给的数据结构是怎样的了,如果后端给的数据结构是扁平的,那就是如上的扁平结构的配置,如果是树结构的数据,则使用树结构的配置。