天天看點

使用SpringMVC架構的項目樹形結構菜單功能的實作

當選擇的節點具有單一性質時,樹形結構菜單在項目中會經常使用到。這裡,筆者就以執行個體介紹一下樹形菜單功能的實作。效果如下圖所示:

使用SpringMVC架構的項目樹形結構菜單功能的實作
使用SpringMVC架構的項目樹形結構菜單功能的實作

實作樹形菜單主要的思路:前端向伺服器發送請求,擷取伺服器響應的資料,解析資料,顯示成樹形菜單,最關鍵的兩點就是:第一,前端需要什麼樣的資料?樹形菜單需要的資料無非就是一個對象裡面包含一個該對象的集合,具體看前端選擇什麼樣的架構,不使用架構也可以,使用純頁面和原生js也可以實作,隻是樣式,資料解析都得自己寫,這裡,筆者選用layui前端架構,需要的資料是一個分支對象的集合。

第二,背景怎樣包裝資料?背景包裝樹形菜單資料的方法有兩種,第一種是使用for循環,不斷地向集合對象中添加資料,直到最後一個葉子節點;第二種是使用遞歸的方法,周遊所有資料,不斷地調用一個包裝資料的方法,直到最後一個資料。

前端代碼:

<body>
<h2 style="margin-left: 50px;margin-top: 50px">省市區樹形結構菜單</h2>
<ul id="demo" style="margin-left: 50px;margin-top: 10px"></ul>
<script src="../../../layuiadmin/layui/layui.js" type="text/javascript" charset="utf-8"></script>
<script src="../../content/js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../../../layuiadmin/lib/formTools.js" type="text/javascript"></script>
<script type="text/javascript">
    layui.use(['tree', 'layer'], function () {
        var layer = layui.layer;
        var selectedArea=null;
        layui.tree({
            elem: '#demo',
            nodes: formTool.ajax(null, "test/nodes").data,
            click: function (node) {
                layer.msg(node.name+"----"+node.prefecture.prefectureId, {icon: 1});
                selectedArea=node.prefecture.prefectureId;
            }
        });

        $(".layui-tree li a").click(function() {
            if($(".layui-tree li a").hasClass("selectedColor")) $(".layui-tree li a").removeClass("selectedColor");
            $(this).addClass("selectedColor");
        });

    });


</script>
</body>
           

背景實體類代碼:

public class Nodes {
    private String name;
    private Boolean spread;
    private String href;
    private List<Nodes> children;

    private Prefecture prefecture;

    public Prefecture getPrefecture() {
        return prefecture;
    }

    public void setPrefecture(Prefecture prefecture) {
        this.prefecture = prefecture;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getSpread() {
        return spread;
    }

    public void setSpread(Boolean spread) {
        this.spread = spread;
    }

    public String getHref() {
        return href;
    }

    public void setHref(String href) {
        this.href = href;
    }

    public List<Nodes> getChildren() {
        return children;
    }

    public void setChildren(List<Nodes> children) {
        this.children = children;
    }
}
           

背景Controller代碼:

第一種方法:分别查詢,循環包裝資料

/**
     * 分級查詢包裝成List<Nodes>傳回給前台,有幾級就查詢幾次
     */
    @RequestMapping(value = "nodes",method = RequestMethod.POST)
    public NeTableResponse<List<Nodes>> nodes(){
        NeTableResponse<List<Nodes>> json=new NeTableResponse<List<Nodes>>();
        //傳回的Nodes對象的集合
        List<Nodes> nodesList=new ArrayList<>();
        List<Prefecture> prefectureProvince = nodesService.queryProvince();
        //周遊省
        for (Prefecture province:prefectureProvince) {
            Nodes nodesProvince=new Nodes();
            nodesProvince.setName(province.getPrefecture());
            nodesProvince.setPrefecture(province);
            List<Prefecture> prefectureCity = nodesService.queryChildren(province.getPrefectureId());
            List<Nodes> nodesCityList=new ArrayList<>();
            //周遊市,并添加到所屬的省
            for (Prefecture city:prefectureCity) {
                Nodes nodesCity=new Nodes();
                nodesCity.setName(city.getPrefecture());
                nodesCity.setPrefecture(city);
                List<Prefecture> prefectureCountry= nodesService.queryChildren(city.getPrefectureId());
                List<Nodes> nodesCountryList=new ArrayList<>();
                //周遊區縣,并添加到所屬的市
                for (Prefecture country:prefectureCountry) {
                    Nodes nodesCountry=new Nodes();
                    nodesCountry.setName(country.getPrefecture());
                    nodesCountry.setPrefecture(country);
                    nodesCountryList.add(nodesCountry);
                }
                nodesCity.setChildren(nodesCountryList);
                nodesCityList.add(nodesCity);
            }
            nodesProvince.setChildren(nodesCityList);
            nodesList.add(nodesProvince);
        }
        return json.setData(nodesList);
    }
           

第二種方法:使用遞歸周遊資料包裝資料

/**
     * 先查詢出所有,然後使用遞歸包裝資料,隻查詢一次
     */
    @RequestMapping(value = "getNodes",method = RequestMethod.POST)
    public NeTableResponse<List<Nodes>> getNodes(){
        NeTableResponse<List<Nodes>> json=new NeTableResponse<List<Nodes>>();
        //查詢所有的地區
        List<Prefecture> prefectureAll = nodesService.queryAll();
        List<Nodes> nodesList = this.packNodes(prefectureAll, 1);
        return json.setData(nodesList);
    }

    /**
     * 對查詢的所有結果遞歸周遊
     */
    private List<Nodes> packNodes(List<Prefecture> prefectureAll,Integer code){
        List<Nodes> nodesList=new ArrayList<>();
        for (Prefecture prefecture:prefectureAll) {
            if (prefecture.getPrefectureLevel()==code){
                Nodes nodes=new Nodes();
                nodes.setName(prefecture.getPrefecture());
                nodes.setPrefecture(prefecture);
                nodes.setChildren(this.packNodes(prefectureAll,Integer.parseInt(prefecture.getPrefectureId())));
                nodesList.add(nodes);
            }else if(String.valueOf(code).equals(prefecture.getSupPrefectureId())){
                Nodes nodes=new Nodes();
                nodes.setName(prefecture.getPrefecture());
                nodes.setPrefecture(prefecture);
                if(prefecture.getLastStage()!=1) nodes.setChildren(this.packNodes(prefectureAll,Integer.parseInt(prefecture.getPrefectureId())));
                nodesList.add(nodes);
            }
        }
        return nodesList;
    }
           

這裡發現了IDEA開發工具的另一個智能的地方,如果使用了遞歸,左側會有遞歸recursion的辨別,如下圖:

使用SpringMVC架構的項目樹形結構菜單功能的實作

繼續閱讀