Z-tree 统计每一父节点的叶子节点数(看这一篇就够了)
最近刚走出校园的我找到了第一份工作,在入职考核中就遇见了一道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 统计每一父节点的叶子节点数(看这一篇就够了)的更多相关文章
- Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框
Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框 Jquery EasyUI Combotree单选框,Jquery EasyUI Combotree只能选择叶子节点 ...
- MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)
背景说明 需求:MySQL树形结构, 根据指定的节点,获取其下属的所有子节点(包含路径上的枝干节点和叶子节点) 枝干节点:如果一个节点下还有子节点,则为枝干节点. 叶子节点:如果一个节点下不再有子节点 ...
- 找出所有从根节点到叶子节点路径和等于n的路径并输出
//找出所有从根节点到叶子节点路径和等于n的路径并输出 Stack<Node> stack = new Stack<Node>(); public void findPath( ...
- 求二叉树的深度,从根节点到叶子节点的最大值,以及最大路径(python代码实现)
首先定义一个节点类,包含三个成员变量,分别是节点值,左指针,右指针,如下代码所示: class Node(object): def __init__(self, value): self.value ...
- Ext.jsTree 向子节点添加叶子节点
// 定义搜索节点树结构Store const nodeStore = Ext.create('Ext.data.TreeStore', { autoLoad : true, id : 'nodeSt ...
- 根节点到叶子节点路径之和为target
//递归吧,但是在递归到底的条件上要判断好,比如说完整路径是到叶子节点,也就是说左右子节点都为空,并且这时候的root.val==target表示找到了一个list,再返回. 但是因为我并没有直接就用 ...
- easyui tree 判断是否是叶子节点
<input class="add" id="add" style="display: none" type="submit ...
- hdu 2196 叶子节点最长距离(树DP)
http://www.cnblogs.com/kuangbin/archive/2012/08/28/2659915.html 求每个节点到叶子节点的最长距离 需要保存每个节点到叶子节点距离的最大值和 ...
- LC: 404.左叶子节点
计算给定二叉树的所有左叶子之和. 示例: / \ 9 20 / \ 15 7 ,所以返回 24 解析 我们需要找到这样的节点 属于叶子节点 属于父节点的左子节点 方法一:用栈,dfs遍历,用全局变量r ...
随机推荐
- Jordan标准形
一.引入 前面已经指出,一切n阶矩阵A可以分成许多相似类.今要在与A相似的全体矩阵中,找出一个较简单的矩阵来作为相似类的标准形.当然以对角矩阵作为标准形最好,可惜不是每一个矩阵都能与对角矩阵相似.因此 ...
- win10笔记本实现双屏显示的自如切换
前言 使用电脑的过程中想一边看内容,一边进行编辑,这就涉及到双屏显示并实现扩展分屏,本文就介绍一下这些操作. 工具 win10-thinkpad-E470:另一块显示屏(博主的是戴尔的显示器):一条外 ...
- specified属性
- Tomcat问题:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined ,At least one of these environment variable is needed to run this program
一眼就能看出来是jdk的环境有问题,但是用了这么久的jdk一直都配置的好好的,怎么一到Tomcat上就这么矫情了. 最后查解决方案,原来是我的jdk从官网直接下载的,虽然我修改了java_home,但 ...
- 20155207 2006-2007-2 《Java程序设计》第5周学习总结
20155207 2006-2007-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 语法与继承架构 Java中的错误以对象方式呈现为 java.lang.Throwab ...
- Windows10中启用原来的Windows照片查看器方法
前言: ============================================== Windows10 版系统自带很多垃圾应用,图片查看器弄得很不好用,还是习惯Windows7的,自 ...
- python pandas Timestamp 转为 datetime 类型
In [11]: ts = pd.Timestamp('2014-01-23 00:00:00', tz=None) In [12]: ts.to_pydatetime() Out[12]: date ...
- IE7下对某些seajs压缩文件不兼容的解决方法
seajs.config({ comboExcludes: /common.js/ }) (杨磊哥提供)
- MySQL Disk--SSD磁盘性能抖动问题
============================================================= SSD性能 空盘性能:SSD出厂时磁盘没有任何数据情况下的性能 稳态性能:当 ...
- Apache2.4配置(全)
http://blog.csdn.net/u012291157/article/details/46492137