最近刚走出校园的我找到了第一份工作,在入职考核中就遇见了一道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]);
}
}
} }

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

Z-tree 统计每一父节点的叶子节点数(看这一篇就够了)的更多相关文章

  1. Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框

    Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框 Jquery EasyUI Combotree单选框,Jquery EasyUI Combotree只能选择叶子节点 ...

  2. MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)

    背景说明 需求:MySQL树形结构, 根据指定的节点,获取其下属的所有子节点(包含路径上的枝干节点和叶子节点) 枝干节点:如果一个节点下还有子节点,则为枝干节点. 叶子节点:如果一个节点下不再有子节点 ...

  3. 找出所有从根节点到叶子节点路径和等于n的路径并输出

    //找出所有从根节点到叶子节点路径和等于n的路径并输出 Stack<Node> stack = new Stack<Node>(); public void findPath( ...

  4. 求二叉树的深度,从根节点到叶子节点的最大值,以及最大路径(python代码实现)

    首先定义一个节点类,包含三个成员变量,分别是节点值,左指针,右指针,如下代码所示: class Node(object): def __init__(self, value): self.value ...

  5. Ext.jsTree 向子节点添加叶子节点

    // 定义搜索节点树结构Store const nodeStore = Ext.create('Ext.data.TreeStore', { autoLoad : true, id : 'nodeSt ...

  6. 根节点到叶子节点路径之和为target

    //递归吧,但是在递归到底的条件上要判断好,比如说完整路径是到叶子节点,也就是说左右子节点都为空,并且这时候的root.val==target表示找到了一个list,再返回. 但是因为我并没有直接就用 ...

  7. easyui tree 判断是否是叶子节点

    <input class="add" id="add" style="display: none" type="submit ...

  8. hdu 2196 叶子节点最长距离(树DP)

    http://www.cnblogs.com/kuangbin/archive/2012/08/28/2659915.html 求每个节点到叶子节点的最长距离 需要保存每个节点到叶子节点距离的最大值和 ...

  9. LC: 404.左叶子节点

    计算给定二叉树的所有左叶子之和. 示例: / \ 9 20 / \ 15 7 ,所以返回 24 解析 我们需要找到这样的节点 属于叶子节点 属于父节点的左子节点 方法一:用栈,dfs遍历,用全局变量r ...

随机推荐

  1. Redis----windows下的常用命令

    1:首先下载redis.从下面地址下:https://github.com/MSOpenTech/redis/releases2:创建redis.conf文件:这是一个配置文件,指定了redis的监听 ...

  2. C语言基础:内存 分类: iOS学习 c语言基础 2015-06-10 21:59 23人阅读 评论(0) 收藏

    全局变量:定义在函数之外.(不安全)   局部变量;定义在函数之内. 内存的划分:1栈区   2堆区  3静态区(全局区) 4常量区 5代码区 栈区..静态区.常量区.代码区的数据都是由系统分配和释放 ...

  3. Qemu编译qemu-system-arm

    /********************************************************************************* * Qemu编译qemu-syst ...

  4. c++ 字符数组-print and 写入文件

    1.print ][] = { }; method1: 为了打印出unsigned char数据所对应的数值,可以将其强制转换成int类型,并做打印输出. std::cout << ][] ...

  5. MyEclipse 2014 破解图文详细教程

    一.安装完成MyEclipse2014(适用于2013等版本)后,不要打开软件,下载破解附件包. 破解附件包下载地址:点我下载 二.解压破解文件压缩包,得到一下文件列表: 三.双击run.bat,即可 ...

  6. WinRAR备份技巧 - imsoft.cnblogs

    RAR控制台日常备份策略 run.batrar a -ep1 -agYYYY{年}MM{月}DD{日} 备份 @list.txt-ep1是忽略原文件路径,rar包里是一堆文件,没有目录结构-ag附加命 ...

  7. C/S架构和B/S架构

    本文内容整理自http://blog.csdn.net/tennysonsky/article/details/45062079 C/S架构和B/S架构是两种颇具影响力的软件体系结构.C/S是一种历史 ...

  8. ajax 跨域的问题 用js绕过跨域

    之前遇到一个ajax跨域的问题,搜索了很多方法才找到解决方案,也怪自己  菜鸟一个 这些经验还是要慢慢来的 尤其是最近来回顾一下 竟然发现自己忘记了  所以还是把它记下来啊 免得到时候忘记 这个方法原 ...

  9. 蓝桥杯 ALGO-1:区间k大数查询

      算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB        问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个 ...

  10. 斐波那契数列的5种python实现写法

    斐波那契数列的5种python写法       斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖 ...