ztree成树结构的关键条件

229 阅读2分钟
最近在使用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)
        })
      }
    },
  }
}

二、到底是使用扁平数据结构还是树数据结构?

那就要看后端给的数据结构是怎样的了,如果后端给的数据结构是扁平的,那就是如上的扁平结构的配置,如果是树结构的数据,则使用树结构的配置。