菜鸟笔记: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": null
31    },
32    {
33        "id": 7,
34        "name": "777",
35        "parent": 5,
36        "icon": null
37    },
38    {
39        "id": 9,
40        "name": "8888",
41        "parent": 1,
42        "icon": nullmysql安装教程菜鸟课程
43    },
44    {
45        "id": 10,
46        "name": "9999",
47        "parent": 9,
48        "icon": null
49    },
50    {
51        "id": 11,
52        "name": "10000",
53        "parent": 1,
54        "icon": null
55    }
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对象
代码:
('/:id', function(req, res, next) {
2
3
4  Connection(function(err, connection) {
5if (err) return next(err);
6
7      connection.query('SELECT * from menuitems ', function(err, rows, fields) {
8if (err) throw err;
9//get all data
10var result = [];//存放起始对象
11var allMenu = rows;//获取sql出的全部json对象
12for(i=0;i<allMenu.length;i++){
13if(allMenu[i].id == req.params.id){
14            result.push(allMenu[i]) ;//根据id号获取根对象
15break;
16          }
17        }
18//judege result exist or not
19if(result.length==0){
20
21return 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 child
31function findItemChild(item){
32var arrayList=[];
33for(var i in allMenu){
34if(allMenu[i].parent == item.id){
35              arrayList.push(allMenu[i]);
36            }
37          }
38return arrayList;
39        }
40//get all child
41function getAllChild(array){
42var childList=findItemChild(array[0]);
43if(childList == null){
44return [];
45          }
46else{
47for(var j in childList){
48              childList[j].sub=[];
49              childList[j].sub=getAllChild([childList[j]]);
50            }
51            array[0].sub=childList;
52          }
53return 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数据构成的森林。思想是通过给森林构造⼀个根节点转换为树,再利⽤上述⽅法实现。
('/', function(req, res, next) {
2
3  Connection(function(err, connection) {
4if (err) return next(err);
5    connection.query('SELECT * from menuitems ', function(err, rows, fields) {
6if (err) throw err;
7//get all data
8//create a id= null root for forest
9var temp_parent={"id":null,"sub":[]};//新建id为null的对象做为森林的根
10var result=[];
11var allMenu = rows;
12
13        result.push(temp_parent) ;
14
15var output = getAllChild(result);
16if(output.length==0){
17//if our database do note have any data
18return res.json('Failed! do not have any data!');
19      }else {
20        res.json(output);
21      }
22
23//find some item all child  //⽅便阅读依然放上此⽅法
24function findItemChild(item){
25var arrayList=[];
26for(var i in allMenu){
27if(allMenu[i].parent == item.id){
28            arrayList.push(allMenu[i]);
29          }
30        }
31return arrayList;
32      }
33//get all child          //⽅便阅读依然放上此⽅法
34function getAllChild(array){
35var childList=findItemChild(array[0]);
36if(childList == null){
cssci集刊2021
37return [];
38        }
continue跳出for循环
39else{
40for(var j in childList){
41            childList[j].sub=[];
42            childList[j].sub=getAllChild([childList[j]]);
43          }
44          array[0].sub=childList;
45        }
46return childList;
47
mysql打不开
48      }
49
50      });
51
52 });
53 });
总结:通过javascript语⾔利⽤NodeJS结合mysql可以实现从后台拿到JSON数据后,将数据构造成树状结构的形式供前端使⽤。这种Javascript全栈开发⽅式还有很多需要学习。未来的路还很长,加油!
递归的写法需要时常琢磨寻好的返回⽅式,在本⽂的思想下,递归⽅法的输⼊与返回的形式应统⼀,防⽌程序陷⼊死循环或不可执⾏,实在⽆法下⼿时应该通过画流程图的形式判断递归的有效性。递归在树层级⽐较深时肯定会耗费⼤量计算时间,因此之后通过学习寻更好的解决⽅法。
linux常用编辑命令kotlin教程培训tips:由于本⼈菜鸟⼀枚,所述拙见仅供⾃⼰学习总结,第⼀次写博客~若对您造成错误影响请批评指正。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。