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);
        }
    }
}


评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛乌龟一起走

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值