最近刚走出校园的我找到了第一份工作,在入职考核中就遇见了一道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. ZEDGRAPH画图心得,SQL语句构造!!!

    /// <summary> /// 画折线 /// </summary> public void Drawline() { OleDbConnection odcConnect ...

  2. sql,用 ISNULL(), NVL(), IFNULL() and COALESCE() 函数替换空值

    在数据库操作中,往往要对一些查询出来的空值进行替换,如函数SUM(),这个函数如果没有值会返回NULL,这是我们不希望看到的, 在MySQL中我们可以这样来写: ) ... 在SQLSERVER中我们 ...

  3. 2.3 linux中的信号分析 阻塞、未达

    信号的阻塞.未达: linux中进程1向进程2发送信号,要经过内核,内核会维护一个进程对某个信号的状态,如下图所示: 当进程1向进程2发送信号时,信号的传递过程在内核中是有状态的,内核首先要检查这个信 ...

  4. CodeForces - 547D: Mike and Fish (转化为欧拉回路)(优化dfs稠密图)(定向问题)

    As everyone knows, bears love fish. But Mike is a strange bear; He hates fish! The even more strange ...

  5. JQ和JS获取span标签的内容(有的情况下JQ达不到预期的目的就用JS)

    https://www.cnblogs.com/anniey/p/6439021.html <span id="content">‘我是span标签的内容’</s ...

  6. cin和cout详解

    无论输入数字还是字符串,一个回车键是把输入的这个东西送到变量中,可以一次性送到 一个(或者多个)空格键是分隔这些值的 cout <<N; for(int i=0;i<5;i++) { ...

  7. hasura-graphql 集成 pipelinedb 1.0.0

    pipelinedb 1.0.0 已经是一个标准的pg 扩展了,同时以前的语法也有变动,但是集成进hasura-graphql 更方便了 使用docker-compose 运行 环境准备 docker ...

  8. VdcEye manager

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011652271/article/details/24878335 VdcEye manager ...

  9. maven工程下的“run as application”

    为了让maven能够在Terminal窗口执行(比在Console执行方便多了,命令行总是比右键选择run要快),需要配置如下的profile:然后敲入  mvn -test -Prun  即可.   ...

  10. Dynamics CRM 2011 快速查找 出现异常 QuickFindQueryRecordLimit exceeded. Cannot perform this operation 的解决方法

    一.CRM 2011 快速查找,输入编号的签名几个字母发现查询很慢. 图 1 当然在图1 上右边的出入框输入编号的部分的时候,有时候会发现数据在加载中..,非常慢,通过Crm Trace Log Vi ...