zTree 是一个依靠 jQuery 实现的多功能 “树插件”。使用zTree会涉及到一些操作的逻辑,例如增加节点、删除节点等,下面我简要描述一下实际使用中的一点心得。
zTree的节点json设计(也就是你后台的数据库设计)可以采用以下设计格式,每一个节点由id、pId、level、name等字段构成,另外可添加一个relation字段来表示各节点直接的联系,例如一级节点(id为1)可作0.,二级节点可作0.1.(以‘.’号结尾)。其它的node格式可参考zTree官网demo www.treejs.cn/v3/main.php#_zTreeInfo:
var zNodes =[{id:1, pId:0, level:1, name:"test", open:true}];
有了上述的格式后便可开始实际的操作了,比如异步获取数据(async,此setting在zTree的官方api上有对应内容),当然我们现在要讲的内容是对节点的操作,对其它内容不做拓展,请读者自行查阅zTree官方文档。
假设有API(以Restful API设计格式):
1. POST /api/node
2. GET /api/nodes
...
对于新增节点来说,存在着新增根节点与新增子节点两种情况:
对于新增根节点,父节点为0,层级为1,将节点对应的data={pId:0,level:1,name:'xxx}通过ajax或其它手段使用POST api路径(POST /api/node)向后台请求即可(id应该不重复,mysql可设置自增,mongodb本身则生成一条id不重复的文档);
对于新增子节点,父节点为上一级节点id,层级为父节点层级加1,下一步新增操作如上新增根节点一致。
新增节点的逻辑大致如下:
对于获取树节点,这里有一个点容易弄混,就是树的作用。对于树来说,它应该只作为一个数据的索引,而不是说通过请求后台api就要将所有的data(你想展示的内容,或者说你的业务逻辑需要用到的数据)都在树上展示出来(如果需要将data展示出来为什么不能直接用循环来将data放置在多个div块呢?)。树展示的节点应该尽量简洁,例如zTree官网展示的demo只显示了节点的名称。
那么此时读者可能会问:那么对应节点的数据应该怎么展示呢?
这个问题可以用两种方式来解答,第一,如果在向后台请求时(GET /api/nodes),返回的json存在data,那么则在点击zTree上节点时(点击时提供一个回调函数,函数的参数其中之一即为当前节点的信息),可通过各种形式模态框、iframe内嵌的页面或你想使用的dom形式来展示对应节点的信息。
第二,可以通过对应节点的id来发起请求例如(/api/node/1),以此来获得对应节点的信息。
对于以上两种形式,个人比较推崇后者。生成树时只需要一些很简单的字段(id,pid,name等),考虑这种情况,我们想要生产的树的节点映射的是一个个文档,那么假设文档(doc)除了上述简单字段外还有content、status,doc_html等其它内容。
站在生成树的角度来说,使用第一种方式,如果在获取节点时,直接将节点的所有字段全数返回,那么很明显对于生成树是很冗余的,并且当doc的content或doc_html内容较长,大小过大时必然会影响树的生成性能,本来10ms的事弄成需要100ms就得不偿失了。
另一方面,使用第二种方式,对于获取节点信息或操作信息本身和生成树就是处在不同的业务范围内,不应该放在同一个维度上来处理;并且在获取信息时,不同的操作需要用到的信息也会不同,例如当查看doc信息时,只需要看到doc_html、当修改doc信息时,需要使用到content、status等信息;基于原子操作,当使用第一种方式时,如果文档doc_a是公用的,有两个人在一段很短的时间内操作该文档(假设A用户、B用户均已打开页面并在操作期间没有进行页面刷新),A用户在查看doc_a而B用户在修改doc_a,当B用户在修改doc_a完成后,A用户点击doc_a对应节点,显然A用户并没有获取到更新后的doc_html,而使用第二种方式则能通过发起请求获取到修改后的数据信息。
以上就是我向讨论一点点内容,才疏学浅,请各位指教,另外如果希望看一下对应的内容可以看我的github的PDoc(前端使用的树不是用的zTree,用的是element-ui的树但是大同小异,后台用的node,欢迎各位star,各位提issue,各位拍砖~),下附地址: