Z-tree 统计每一父节点的叶子节点数(看这一篇就够了)

时间:2023-02-05 23:48:22

最近刚走出校园的我找到了第一份工作,在入职考核中就遇见了一道Z-tree的试题

这道题目本身是不难的,但是我第一次接触这个插件而且还把解决问题的方向搞错了,弄的我好几天都很难受。

弄得我都开始怀疑人生,甚至开始怀疑自己是否适合做编程。

为了纪念这个 恶心了我好几天的试题 我决定谨以此篇纪念我无处安放的青春

题目要求

要求从后台的数据库里面把一个公司部门和员工的信息用Z-tree显示出来(这个很简单!)

并且每一个父节点都要显示下方叶子节点的个数,最顶层的根结点的显示的数量要由下方的子父节点统计的数量累计和一致

(PS.不管多深都要显示的正确的)

我呢,开始以为这些叶子节点的数量是用SQL语句查出来的

就拼命的去用sql的函数去写递归,但是总是说我的返回结果字段太长,就因为这样我钻了牛角尖

下面说一下正解

我用的数据库里是有两张表的 一张是department部门的关系表    另一张是  users 一个员工的信息表

员工信息表的内容是和 部门表有对应的字段的

表的具体内容我就不列出来了

下面我来具体说一说如何用递归的方法查出来叶子节点的数量的吧

思路呢 是这样的

我们要先获取到 Ztree的所有子节点 然后逐级进行遍历统计

核心代码如下:

这个是有回调函数的那种(不是一次性计算完),效果就是你每点开一级父文件才会统计下面的叶子节点数

$(function(){//页面加载完成
ajaxFun();
}); function ajaxFun(){
$.ajax({
url:"index.php",//连接后台的地址
type:"post",//定义数据的传输方式
data:{
type:'get_date'
},//向后台发送的数据
success:function(data){//连接成功后接收后台的数据
$all_data = eval(data);//接收后台数据
console.log($all_data);
var setting = {
callback: {
onExpand: expandNode,//节点被展开时计算子节点下的叶子节点的数目
},
data: { simpleData: {
enable: true,
}
}, }; $data1=$all_data[0];//部门关系
$data2=$all_data[1];//人员所属的 部门 以及组
var zNodes =[];//定义zNodes json数组 组织数据
for(var i in $data1){//填充部门数据
var flag = false;
zNodes.push({id:$data1[i].code, pId:$data1[i].father_code, name:$data1[i].name+"(0)",isParent:true});
} for(var i in $data2){//填充人员数据
zNodes.push({id:$data2[i].userid, pId:$data2[i].father_code, name:$data2[i].username});
}
//console.log(zNodes);
$.fn.zTree.init($("#treeDemo"), setting, zNodes);//加载Z-tree
initNodeNum(); //调用第一次页面加载完成计算最上层节点下所有子节点的方法
} });
} function initNodeNum(){ var zTree = $.fn.zTree.getZTreeObj("treeDemo");//获取加载后的z-tree对象
var nodes = zTree.getNodes();//获取 zTree 的全部节点数据
for (var i=0, l=nodes.length; i < l; i++)//遍历节点数据
{
var nodeId = nodes[i].id;//记录节点id
var nodeName = nodes[i].name;//记录节点名称
var isParent = nodes[i].isParent;//记录节点是否是父
var pId = nodes[i].pId;//记录节点父id
if(isParent&&pId ==null){//如果是父节点并且Pid是空
var childArr =[];//定义数组存放子节点
childArr = getAllChildrenNodes(nodes[i],childArr);
var str = nodeName.substring(0,nodeName.length-2);//去掉括号
var newname = str+childArr.length+')';//计算上节点数并加上括号
nodes[i].name = newname;//重新命名
zTree.updateNode(nodes[i]);//并更新节点信息
} } } function getAllChildrenNodes(treeNode, result) {//给定一个节点对象
if (treeNode.isParent) {//如果是父
var childrenNodes = treeNode.children;
if (childrenNodes) {
for (var i = 0; i < childrenNodes.length; i++) {
if (!childrenNodes[i].isParent){ //只要叶子节点
result.push(childrenNodes[i].id);
}
result = getAllChildrenNodes(childrenNodes[i], result);
}
}
}
return result;
}
function expandNode(event, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"); if (treeNode.isParent) {
var childrenNodes = treeNode.children;
if (childrenNodes) {
for (var i = 0; i < childrenNodes.length; i++) {
if(!childrenNodes[i].isParent)continue;
var nodeName = childrenNodes[i].name;
var childArr =[];
childArr = getAllChildrenNodes(childrenNodes[i],childArr);
var str = nodeName.substring(0,nodeName.length-2);
var newname = str+childArr.length+')';
childrenNodes[i].name = newname;
zTree.updateNode(childrenNodes[i]);
}
}
} }

还有一种是没有回调的那种的,这种是一次性计算出来的,比较符合线上的需求

代码如下:

 $(function(){//页面加载完成
ajaxFun();
}); function ajaxFun(){
$.ajax({
url:"index.php",//连接后台的地址
type:"post",//定义数据的传输方式
data:{
type:'get_date'
},//向后台发送的数据
success:function(data){//连接成功后接收后台的数据
$all_data = eval(data);//接收后台数据
console.log($all_data);
var setting = {
callback: {
//取消回调函数
},
data: { simpleData: {
enable: true,
}
}, }; $data1=$all_data[0];//部门关系
$data2=$all_data[1];//人员所属的 部门 以及组
var zNodes =[];//定义zNodes json数组 组织数据
for(var i in $data1){//填充部门数据
var flag = false;
zNodes.push({id:$data1[i].code, pId:$data1[i].father_code, name:$data1[i].name+"(0)",isParent:true});
} for(var i in $data2){//填充人员数据
zNodes.push({id:$data2[i].userid, pId:$data2[i].father_code, name:$data2[i].username});
}
//console.log(zNodes);
$.fn.zTree.init($("#treeDemo"), setting, zNodes);//加载Z-tree
initNodeNum(); //调用第一次页面加载完成计算最上层节点下所有子节点的方法
} });
} function initNodeNum(){ var zTree = $.fn.zTree.getZTreeObj("treeDemo");//获取加载后的z-tree对象
var nodes = zTree.getNodes();//获取 zTree 当前显示的节点数据
var nodess = zTree.transformToArray(nodes)//获取所有节点
for (var i=0, l=nodess.length; i < l; i++)//遍历节点数据
{
var nodeId = nodess[i].id;//记录节点id
var nodeName = nodess[i].name;//记录节点名称
var isParent = nodess[i].isParent;//记录节点是否是父
var pId = nodess[i].pId;//记录节点父id
if(isParent){//如果是父节点
var childArr =[];//定义数组存放子节点
childArr = getAllChildrenNodes(nodess[i],childArr);//在这里去循环调用计算子节点的方法
var str = nodeName.substring(0,nodeName.length-2);//去掉括号
var newname = str+childArr.length+')';//计算上节点数并加上括号
nodess[i].name = newname;//重新命名
zTree.updateNode(nodess[i]);//并更新节点信息
} } }
//这个方法就是递归没跑了
//就是 给定一个节点对象 和返回结果的变量(我这里用的是数组)
//就会将这个父节点下面的所有的叶子节点的id记录到一个数组当中
//直到没有父节点了,返回后我们可以计算这个数组的长度就可以知道这个
//父级节点下到底有多少个叶子节点了
function getAllChildrenNodes(treeNode, result) {//给定一个节点对象
if (treeNode.isParent) {//如果是父
var childrenNodes = treeNode.children;
if (childrenNodes) {
for (var i = 0; i < childrenNodes.length; i++) {
if (!childrenNodes[i].isParent){ //只要叶子节点
result.push(childrenNodes[i].id);
}
result = getAllChildrenNodes(childrenNodes[i], result);
}
}
}
return result;
}     //这个是之前的不用的回调了,就先放在这里了
function expandNode(event, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"); if (treeNode.isParent) {
var childrenNodes = treeNode.children;
if (childrenNodes) {
for (var i = 0; i < childrenNodes.length; i++) {
if(!childrenNodes[i].isParent)continue;
var nodeName = childrenNodes[i].name;
var childArr =[];
childArr = getAllChildrenNodes(childrenNodes[i],childArr);
var str = nodeName.substring(0,nodeName.length-2);
var newname = str+childArr.length+')';
childrenNodes[i].name = newname;
zTree.updateNode(childrenNodes[i]);
}
}
} }

好了我的分享到这里了 ,有疑问 的小伙伴可以私信我,我们可以一起探讨!!!