由于最近在边学边做一些前端的内容,公司用到了easyui ,里面需要实现一颗目录树(如下图)
组织树的json格式如图
那么后台如果是要拼接成这样的数据格式给前端,数据量一大,用户一多,就麻烦了,所以现在要通过后台的数据,前端进行相应的处理,封装成这种格式
一, 关于树的一个想法
传统的数据库存储数据是这样存储的
这样通过parentId 关联到id 来确立一个层级,这样可以通过父节点循环找到每一层的子节点。
这样可以实现到目标,但是如果子树比较多的层级嵌套,那么效率就会比较低下。
改进的方法(这个当然不是原创的啦)
item字段说明
一 ,层级
使用了自身和父关系节点,通过”.” 的方式分隔开来,这样我们在查询的时候,通过 “.”+前面的内容,来得到子树的内容
例如 :
父 节点 item 是 6
要得到所有的子孙节点 item like “.6”
单单得到自己的子节点 item 匹配正则表达式 是 “+[0-9].[“+6+”]{1}”
二 ,逆序
指的是这里的层级的数字不是从小到大的,(例如 1.2.3 这样),
而是从大到小的(例如,3.2.1 这样),
这样做的好处在于可以在sql里使用排序
PS : 如果你想要得到一个升序的形式,你可以在sql里使用排序,便于其他的查询时使用
select item from test1 ORDER BY CAST(item AS signed) ASC
//这里使用CAST 这个函数的目的是为了自然数排序,不清楚的同学自行上百度查
数字从大到小
数字从小到大是做不出来这样的效果的
二 代码的实现
/**
* 这是你要封装的对象,可以改成你需要的数据结构
* */
function Datas(id,name,text,children){
this.id = id ;
this.name = name ;
this.text = text ;
this.children = children ;//这是子树
}
/**
* 修改你请求的路径
* */
var apiUrl = "TreeTest.json";
var dataUpdate ;
var arris ; //用于记录节点是否被使用来减少遍历
/*获取目标树的方式*/
function getTree(){
$.ajax({
url : apiUrl,
type : 'get',
success:function(msg){
//请求成功
dataUpdate = msg ;
arris = new Array(msg.length);
loadTree(getTreeFather(0,arris.length));
},error:function(msg){
//请求失败
},timeout:function(msg){
//请求超时
}
})
}
/*顶级的节点*/
function getTreeFather(index,length){
var lst = new Array();
// 循环判断
while(index < length){
// 控制下标
if(typeof(arris[index]) != "undefined" && arris[index] == 0){
index++;
continue;
}
//打印能够匹配正则的内容
var s = "[0-9]{1}$";
var s1 =new RegExp(s);
//得到下标
var code = dataUpdate[index].userCode;
if(code.search(s1)==0){
current++;
// 打印当前下标的内容
//console.log(dataUpdate[index].userCode);
//改成0,之后都不会再遍历这个节点
arris[index] = 0;
var m = new Datas(dataUpdate[index].id,
dataUpdate[index].name,
dataUpdate[index].userCode,
getTreeSon(index+1,length,"\."+s,code));
lst.push(m);
}
index++;
}
console.log("结束循环,打印树");
console.log(lst);
return lst;
};
/*顶级的节点下的所有层级节点*/
function getTreeSon(index2,length,stringCode,scode){
var lst2 = new Array();
// 跳出循环判断
while(index2 < length){
// 控制下标
if(typeof(arris[index2]) != "undefined" && arris[index2] == 0){
index2++;
continue;
}
//打印能够匹配正则的内容
var s = "[0-9]{1}"+stringCode;
// console.log(s);
var s1 =new RegExp(s);
//得到下标
var code = dataUpdate[index2].userCode;
if(code.search(s1)==0
&& code.indexOf(scode)>=0){
current++;
// 打印当前下标的内容
// console.log(dataUpdate[index2].userCode);
//之后都不能再打印这个下标的内容
arris[index2] = 0;
var m = new Datas(dataUpdate[index2].id,
dataUpdate[index2].name,
dataUpdate[index2].userCode,
getTreeSon(index2+1,length,"\."+s,code));
lst2.push(m);
}
index2++;
}
return lst2;
};
最终出来的数据格式
把它丢进easyui的效果