有做过网站菜单的童鞋,都知道树级结构,因为展开的形式就是一棵树一样,有父节点、子节点。实现树级结构菜单的形式有很多,例如主从表的形式,一张表存父节点,一张表存子节点,这种方式可能存在一种问题,就是只能支持两级,并且不容易进行扩展。在这里,我想讲的是另一种形式,单表存储的方式。即一张表里面既有子节点,又有父节点,然后实现树级结构,具体介绍请往下看:
如上图可以看到,每一条记录都有一个pid,代表的是父节点的ID,这里我们的菜单根节点,也就是最大的父节点的ID为-1,其他的都是他的子孙们。
要想对这种数据进行组织形成最后的树级结构,需要才要递归算法,递归怎么理解?你就想它自己在不断调用自己就行了,当然,你需要注意的是它有一个特点,就是肯定有一个跳出递归的条件,否则岂不是会进入死循环吗?
public Map queryMenus(Map prams){
List
如代码所示,每次将一个子节点作为父节点,递归调用查找子节点方法,直到所有的子节点都找完,返回主方法,递归结束。
{
"menus": [
[
{
"code": "P2300",
"i18nid": 361,
"useflag": 1,
"icon": "icon-blank",
"pid": -3,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "VUE",
"id": 656,
"seq": 0
}
],
[
{
"code": "Report",
"i18nid": 8,
"useflag": 1,
"icon": "icon-report",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "zh_CN",
"name": "统计报表",
"id": 137,
"seq": 40
},
{
"code": "BoardMgr",
"i18nid": 331,
"useflag": 1,
"icon": "icon-setting",
"pid": -2,
"functionurl": "./Board/BoardUrlIndex",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "看板管理",
"id": 376,
"seq": 50
},
{
"code": "DeviceMgr",
"i18nid": 6,
"useflag": 1,
"icon": "icon-devicemgr",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [
{
"code": "MonitorDevAlarm",
"i18nid": 273,
"useflag": 1,
"icon": "icon-blank",
"pid": 66,
"functionurl": "./Technics/MonitorDevAlarm",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "设备告警",
"id": 599,
"seq": 15
},
{
"code": "DeviceRecord",
"i18nid": 278,
"useflag": 1,
"icon": "icon-blank",
"pid": 66,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [
{
"code": "MaintainOperate",
"i18nid": 285,
"useflag": 2,
"icon": "icon-blank",
"pid": 616,
"functionurl": "./Device/MaintainOperate",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "保养次数",
"id": 621,
"seq": 3
},
{
"code": "SpotCheckOperate",
"i18nid": 286,
"useflag": 2,
"icon": "icon-blank",
"pid": 616,
"functionurl": "./Device/SpotCheckOperate",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "点检次数",
"id": 622,
"seq": 6
}
],
"i18ntype": "",
"name": "设备履历",
"id": 616,
"seq": 3
}
],
"i18ntype": "zh_CN",
"name": "设备管理",
"id": 66,
"seq": 10
},
{
"code": "systool",
"i18nid": 12,
"useflag": 1,
"icon": "icon-systool",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "zh_CN",
"name": "开发关联",
"id": 1,
"seq": 99
},
{
"code": "系统管理",
"i18nid": 11,
"useflag": 1,
"icon": "icon-sysmgr",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "zh_CN",
"name": "系统管理",
"id": 5,
"seq": 98
},
{
"code": "OrderMgr",
"i18nid": 4,
"useflag": 1,
"icon": "icon-order",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "zh_CN",
"name": "工单管理",
"id": 11,
"seq": 0
},
{
"code": "ProduceMonit",
"i18nid": 333,
"useflag": 1,
"icon": "icon-producemonit",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "生产管理",
"id": 22,
"seq": 5
},
{
"code": "Technics",
"i18nid": 5,
"useflag": 1,
"icon": "icon-technics",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "zh_CN",
"name": "工艺管理",
"id": 575,
"seq": 20
},
{
"code": "NotifyMgr",
"i18nid": 9,
"useflag": 1,
"icon": "icon-board",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "预警管理",
"id": 578,
"seq": 49
},
{
"code": "BasicData",
"i18nid": 10,
"useflag": 1,
"icon": "icon-basicdata",
"pid": -2,
"functionurl": "",
"functionid": "",
"padimg": "",
"children": [],
"i18ntype": "",
"name": "基础数据",
"id": 157,
"seq": 60
}
]
]
}
这里的递归方法有一个不好的地方,就是每次调用的时候,都会传进最大的list,这就导致了,可能同一个节点被循环很多遍。
你有更好的办法解决吗?欢迎留言~~~ 我的另一种方法下回揭晓。