您好,欢迎来到吉趣旅游网。
搜索
您的当前位置:首页菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)

菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)

来源:吉趣旅游网
菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树

状菜单数据接⼝)

初学Web端开发,今天是第⼀次将所学做随笔记录,肯定存在多处⽋妥,望⼤家海涵;若有不⾜,望⼤家批评指正。

进实验室后分配到的第⼀个项⽬,需要制作⼀个不确定层级树形菜单的数据接⼝,对于从来没实战编过程的我,存在太多需要学习的地⽅。开发环境:Atom;语⾔:javascript;

其他:nodejs;mysql;express;

输⼊:通过sql语句转换出的⼀个个JSON对象,如:其中id为唯⼀编号,parent为其⽗级的id号。

1 [ 2 {

3 \"id\": 1,

4 \"name\": \"111\ 5 \"parent\": null, 6 \"icon\": \"555,,\" 7 }, 8 {

9 \"id\": 2,

10 \"name\": \"极地测试菜单2\11 \"parent\": 1,

12 \"icon\": \"/img/002.png\"13 },14 {

15 \"id\": 4,

16 \"name\": \"555\17 \"parent\": 2,18 \"icon\": \"88\"19 },20 {

21 \"id\": 5,

22 \"name\": \"ddd\23 \"parent\": 2,

24 \"icon\": \"555.png\"25 },26 {

27 \"id\": 6,

28 \"name\": \"666\29 \"parent\": 4,30 \"icon\": null31 },32 {

33 \"id\": 7,

34 \"name\": \"777\35 \"parent\": 5,36 \"icon\": null37 },38 {

39 \"id\": 9,

40 \"name\": \"8888\41 \"parent\": 1,42 \"icon\": null43 },44 {

45 \"id\": 10,

46 \"name\": \"9999\47 \"parent\": 9,48 \"icon\": null49 },50 {

51 \"id\": 11,

52 \"name\": \"10000\53 \"parent\": 1,54 \"icon\": null55 }56 ]

输出:树状JSON结构

1 {

2 \"id\": 1,

3 \"name\": \"111\ 4 \"parent\": null, 5 \"icon\": \"555,,\

6 \"sub\": [ 7 {

8 \"id\": 2,

9 \"name\": \"极地测试菜单2\10 \"parent\": 1,

11 \"icon\": \"/img/002.png\12 \"sub\": [13 {

14 \"id\": 4,

15 \"name\": \"555\16 \"parent\": 2,17 \"icon\": \"88\18 \"sub\": [19 {

20 \"id\": 6,

21 \"name\": \"666\22 \"parent\": 4,23 \"icon\": null,24 \"sub\": []25 }26 ]27 },28 {

29 \"id\": 5,

30 \"name\": \"ddd\31 \"parent\": 2,

32 \"icon\": \"555.png\33 \"sub\": [34 {

35 \"id\": 7,

36 \"name\": \"777\37 \"parent\": 5,38 \"icon\": null,39 \"sub\": []40 }41 ]42 }43 ]44 },45 {

46 \"id\": 9,

47 \"name\": \"8888\48 \"parent\": 1,49 \"icon\": null,50 \"sub\": [51 {

52 \"id\": 10,

53 \"name\": \"9999\54 \"parent\": 9,55 \"icon\": null,56 \"sub\": []57 }58 ]59 },60 {

61 \"id\": 11,

62 \"name\": \"10000\63 \"parent\": 1,64 \"icon\": null,65 \"sub\": []66 }67 ]68 }

即将从mysql中取出的⼀条⼀条JSON数据,按照parent所指向的id号,转变为树桩JSON结构,供AngularJS框架⾃动⽣成树桩菜单。⽰例图:

变量声明:allMenu为初始输⼊的JSON数据格式,即包含⼀条⼀条JSON对象的数组。     对象的sub属性放置当前对象的所有⼦节点数组。思想:利⽤递归/循环进⾏树的层级遍历。

   ⽐如输⼊⼀个根节点对象,⾸先应对allMenu遍历寻找parent为根节点id的所有对象(⽅法命名为findItemChild),并将其置⼊⼀个临时数组childlist中。然后对该childlist进⾏遍历,对其中每⼀个对象利⽤递归⽅法,返回该对象的childList并添加进当前对象的sub中,往复递归。举个例⼦:即当⽅法输⼊id=1的对象后,findItemChild⽅法通过遍历会返回⼀个数组[{id:2,parent:1,...},{id:9,parent:1,...},

{id:11,parent:1,...}],之后对该数组进⾏遍历,即将id=2的对象递归输⼊⽅法,并将获取的childlist遍历继续递归。。。。即树的层级遍历。算法:

  输⼊:JSON对象item  function getAllChild(res){

  ①获取所有⽗级为根节点id的⼦对象数组childlist  ②若childlist为空,则返回[]

  ③若childlist不为空,遍历childlist,并对每⼀个childlist[k]递归调⽤getAllChild(childlist[k])赋予childlist[k].sub  ④将childlist输⼊res.sub  ⑤返回childlist  }

输出:以对象item为根节点的树状JSON对象代码:

1 router.get('/:id', function(req, res, next) { 2 3

4 pool.getConnection(function(err, connection) { 5 if (err) return next(err); 6

7 connection.query('SELECT * from menuitems ', function(err, rows, fields) { 8 if (err) throw err; 9 //get all data

10 var result = [];//存放起始对象

11 var allMenu = rows;//获取sql出的全部json对象12 for(i=0;i13 if(allMenu[i].id == req.params.id){

14 result.push(allMenu[i]) ;//根据id号获取根对象15 break;16 }17 }

18 //judege result exist or not19 if(result.length==0){20

21 return res.json('Failed! id is not exist!');22

23 }else{24

25 result.sub=[];

26 result.sub=getAllChild(result);//调⽤27 res.json(result[0]);28

29 }

30 //find some item all child31 function findItemChild(item){32 var arrayList=[];33 for(var i in allMenu){

34 if(allMenu[i].parent == item.id){35 arrayList.push(allMenu[i]);36 }37 }

38 return arrayList;39 }

40 //get all child

41 function getAllChild(array){

42 var childList=findItemChild(array[0]);43 if(childList == null){44 return [];45 }46 else{

47 for(var j in childList){

48 childList[j].sub=[];

49 childList[j].sub=getAllChild([childList[j]]);50 }

51 array[0].sub=childList;52 }

53 return childList;54

55 }56 });57 });58 });

代码执⾏过程:  getAllChild([id=1])

  childlist=[{id:2,parent:1,...},{id:9,parent:1,...},{id:11,parent:1,...}]; for(id=2 id=9 id=11)   ↓

  childlist[id=2].sub=? ↓

getAllChild([id=2]);

           childlist=[{id:4,parent:2,...},{id:5,parent:2,...}];            for(id=4 id=5) ↓

   childlist[id=4].sub=? ↓

                     getAllChild([id=4]);

                       childlist=[{id:6,parent:4,...}];         for(id=6) ↓

   childlist[id=6].sub=? ↓

getAllChild([id=6]),return [];//到底,依次往上返回,将childlist逐步扩充,直到最终返回allchild;

扩充:返回所有树状菜单,即寻找所有JSON数据构成的森林。思想是通过给森林构造⼀个根节点转换为树,再利⽤上述⽅法实现。  

1 router.get('/', function(req, res, next) { 2

3 pool.getConnection(function(err, connection) { 4 if (err) return next(err);

5 connection.query('SELECT * from menuitems ', function(err, rows, fields) { 6 if (err) throw err; 7 //get all data

8 //create a id= null root for forest

9 var temp_parent={\"id\":null,\"sub\":[]};//新建id为null的对象做为森林的根10 var result=[];

11 var allMenu = rows;12

13 result.push(temp_parent) ;14

15 var output = getAllChild(result);16 if(output.length==0){

17 //if our database do note have any data

18 return res.json('Failed! do not have any data!');

19 }else {

20 res.json(output);21 }22

23 //find some item all child //⽅便阅读依然放上此⽅法24 function findItemChild(item){25 var arrayList=[];26 for(var i in allMenu){

27 if(allMenu[i].parent == item.id){28 arrayList.push(allMenu[i]);29 }30 }

31 return arrayList;32 }

33 //get all child //⽅便阅读依然放上此⽅法34 function getAllChild(array){

35 var childList=findItemChild(array[0]);36 if(childList == null){37 return [];38 }39 else{

40 for(var j in childList){41 childList[j].sub=[];

42 childList[j].sub=getAllChild([childList[j]]);43 }

44 array[0].sub=childList;45 }

46 return childList;47

48 }49

50 });51 52 });53 });

总结:通过javascript语⾔利⽤NodeJS结合mysql可以实现从后台拿到JSON数据后,将数据构造成树状结构的形式供前端使⽤。这种Javascript全栈开发⽅式还有很多需要学习。未来的路还很长,加油!

递归的写法需要时常琢磨寻找好的返回⽅式,在本⽂的思想下,递归⽅法的输⼊与返回的形式应统⼀,防⽌程序陷⼊死循环或不可执⾏,实在⽆法下⼿时应该通过画流程图的形式判断递归的有效性。递归在树层级⽐较深时肯定会耗费⼤量计算时间,因此之后通过学习寻找更好的解决⽅法。

tips:由于本⼈菜鸟⼀枚,所述拙见仅供⾃⼰学习总结,第⼀次写博客~若对您造成错误影响请批评指正。   

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- jqkq.cn 版权所有 赣ICP备2024042794号-4

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务