java 遞迴動態實現左側導航欄
阿新 • • 發佈:2019-02-02
之前專案中是使用的最多兩級選單,所以當時寫的是兩個for 迴圈,一旦多層選單,維護起來就麻煩,所以今天使用遞迴實現導航欄動態生成。在這裡主要java 後臺程式碼,以及簡單js 遞迴後臺json 資料。資料庫就沒有在這裡設計。
1、Menu實體類
package com.dairuijie.pojo;
import java.util.List;
/**
* 選單類
*
* @Title: Menu.java
* @Package com.dairuijie.pojo
* @author Drj
* @date 2018年3月2日 下午6:15:00
* @version V1.0
*/
public class Menu {
private String id;
// 選單名稱
private String menuName;
// 父選單id
private String parentId;
// 選單url
private String url;
// 選單圖示
private String icon;
// 選單順序
private int order;
// 子選單
private List<Menu> childMenus;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public List<Menu> getChildMenus() {
return childMenus;
}
public void setChildMenus(List<Menu> childMenus) {
this.childMenus = childMenus;
}
}
2、測試遞迴類
package com.dairuijie.controller; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import com.dairuijie.pojo.Menu; import com.google.gson.Gson; /** * * @Title: MenuTest.java * @Package com.dairuijie.controller * @author Drj * @date 2018年3月2日 下午7:00:56 * @version V1.0 */ public class MenuTest { private static List<Menu> getChild(String id, List<Menu> rootMenu) { List<Menu> childList = new ArrayList<>();//存放直接子選單 /** *開始遍歷二級選單以及它的直接子選單 */ for (Menu menu : rootMenu) { // 遍歷所有節點,將父選單id與傳過來的id比較 if (StringUtils.isNotBlank(menu.getParentId())) {//匯入org.apache.commons.lang3.StringUtils; if (id.equals(menu.getParentId())) {//儘量讓id 在前面,因為他不會為空(資料庫設計為主鍵),parentId 不一定都有值。 childList.add(menu);//相等的話說明這些使它(id)的直接子節點,加入childList } } }//這時候已經將一級選單以及一級的直接子孩子遍歷出來了。 /** * 把子選單的直接子選單再迴圈一遍 * 這時候就是從Menu的直接子選單中獲得需要遍歷的選單也就是childList */ for (Menu menu : childList) { if (StringUtils.isBlank(menu.getUrl())) {//這個判斷的意思是 如果url 不為空說明是最後一個節點,為空說明他不是最後一個子節點,這時候就需要去遍歷 menu.setChildMenus(getChild(menu.getId(), rootMenu));//遞迴 } } if (childList.size() == 0) {// 遞迴退出條件(走到這裡childList 大小等於0 說明該節點就是最後一個) return null; } return childList; } public static void main(String[] args) { List<Menu> rootMenus = new ArrayList<Menu>();//假設是從資料庫查出來的 List<Menu> menuList = new ArrayList<Menu>(); /** * 先找到所有的一級選單 */ for (int i = 0; i < rootMenus.size(); i++) { if (StringUtils.isBlank(rootMenus.get(i).getParentId()) || "0".equals(rootMenus.get(i).getParentId())) {// 一級選單沒有parentId (或是等於0,看怎麼資料庫怎麼設定) menuList.add(rootMenus.get(i)); } } /** * 一級選單之後,開始遞迴子選單 */ for (Menu menu : menuList) { menu.setChildMenus(getChild(menu.getId(), rootMenus)); } Map<String,Object> jsonMap = new HashMap<>(); jsonMap.put("menu", menuList); System.out.println(new Gson().toJson(jsonMap));//json 字串 前端遍歷 } }
3、前端遞迴解析json 資料。
$(function () { var showlist = $("<ul></ul>"); showall(menulist.menulist, showlist); $("#div_menu").append(showlist); }); /** * parent為要組合成html的容器 * menu_list為後臺json資料 */ function showall(menu_list, parent) { for (var menu in menu_list) { //如果有子節點,則遍歷該子節點 if (menu_list[menu].menulist.length > 0) { //建立一個子節點li var li = $("<li></li>"); //將li的文字設定好,並馬上新增一個空白的ul子節點,並且將這個li新增到父親節點中 $(li).append(menu_list[menu].MName).append("<ul></ul>").appendTo(parent); //將空白的ul作為下一個遞迴遍歷的父親節點傳入 showall(menu_list[menu].menulist, $(li).children().eq(0)); } //如果該節點沒有子節點,則直接將該節點li以及文字建立好直接新增到父親節點中 else { $("<li></li>").append(menu_list[menu].MName).appendTo(parent); } } }