1. 程式人生 > >java 遞迴動態實現左側導航欄

java 遞迴動態實現左側導航欄

        之前專案中是使用的最多兩級選單,所以當時寫的是兩個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);
        }
    }
}