1. 程式人生 > >JavaScript處理數據完成左側二級菜單的搭建

JavaScript處理數據完成左側二級菜單的搭建

講解 family 註入 通過 reat amp span hang getmenu

  我們在項目中應用的後臺管理框架基本上都是大同小異,左側是一個二級菜單,點擊選中的菜單,右側對應的頁面展示。我把前端頁面封裝數據的過程整理了一下,雖然不一定適合所有的管理頁面,僅作為案例來參考,只是希望大家能明白實現原理就好。

  左側的菜單的搭建:

   1、首先將我們需要應用的菜單導入數據庫。

    下面的截圖是我導入的數據:

    技術分享

    根據我的業務需求,我需要四個父菜單,所以我將他們的pid字段都設置為0,子菜單的pid字段對應的是父菜單的id,這很重要。url字段就是點擊該菜單時,右側頁面顯示的地址路徑。status狀態字段代表當前菜單的狀態是否可用,我這裏設置的0為可用,1為不可用,稍後會看到。order_num字段這裏暫時用不到。

    2、封裝一個構造函數來讀取並創建二級菜單

    為了不使這個案例太過於繁瑣,在不考慮這個構造函數的靈活性的情況下,我盡量的減少代碼量。假設只是針對本案例,封裝的函數如下:  

function MenuTree(id,url){
    this.id = id;
    this.url = url;
    this.$Div = null;
    this.$curA = null;
    this.initTree();    
}

MenuTree.prototype.initTree = function(){
    var self = this; 
    
//左側菜單的容器,根據元素的id來定義 this.$Div = $("#"+this.id); if(this.$Div.length == 0){ alert("菜單初始化外容器失敗"); return; } //點擊方法的代理,點擊這個容器時會使用this.treeClick定義的方法來代理 this.$Div.click($.proxy(this.treeClick,this)); //向設置好的菜單地址發送請求 $.post(this.url,function(data){ self.createTreeMenu(data.list); },
"json") } MenuTree.prototype.createTreeMenu = function(list){ //若沒有讀取到數據,或者數據長度為0,容器會顯示暫無菜單 if(!list||list.length == 0){ this.$Div.html("暫無菜單"); return; } //聲明一個空對象,用來存放創建的菜單信息 var rootNodes = {}; var len = list.length; var node = null; var curNodeId=""; for(var i=0;i<len;i++){ node = list[i]; //當讀取到的菜單status為1時,代表菜單不可用,跳過 if(node.status==‘1‘) continue; var id = node.id; var name = node.name; var url = node.url; var pid = node.pid; //當本條數據pid為0時,創建這條數據為父菜單 if(pid == "0"){ rootNodes[id] = $("<div class=‘leftTreeMenu hasChildren‘><leftMenuTitle>"+name+"</leftMenuTitle></div>"); continue; } //子菜單的pid是父菜單的id,所以這裏的rootNodes[pid]就是上面的rootNodes[id] var $pnode = rootNodes[pid]; //子菜單創建後要把id和url作為自定義屬性添加到元素上面,後面會用到 var $a = $("<leftTreeNode id=‘leftTreeLink_"+id+"‘>"+name+"</leftTreeNode>").attr("id",id).attr("url",url); $pnode.append($a); //這裏略過不提,下一篇文章講 if(fromURI && (url==fromURI)){ this.$curA = $a.addClass("currentA"); $pnode.addClass("currentMenu").removeClass("hideChildren"); myBar.freshTag(id,name,url); } } var df = document.createDocumentFragment(); for(key in rootNodes){ //appendChild是原生js的用法 //[0]的目的是將jq的對象轉換成dom對象 df.appendChild(rootNodes[key][0]); } (this.$Div)[0].appendChild(df); } MenuTree.prototype.treeClick = function(e){ //click事件,會用到dom和jq的轉換 var target = e.target; var nodeName = target.nodeName; //如果點擊的是父菜單,就通過切換class名字來展示和隱藏子菜單 if(nodeName == "LEFTMENUTITLE"){ $(target).parent().switchClass("hideChildren"); return; } //如果點擊的是子菜單,就處理子菜單的數據 if(nodeName == "LEFTTREENODE"){ this.freshTag($(target)); } } MenuTree.prototype.changeCurNode = function($e){ //如果點擊的與選中的是同一個,就return if(this.$curA == $e) return; //如果this.$curA存在,就將以前的類名currentA移除並子菜單隱藏 if(this.$curA){ this.$curA.removeClass("currentA").parent().removeClass("currentMenu"); } //剛剛點擊的添加類名currentA並顯示子菜單 this.$curA = $e.addClass("currentA"); $e.parent().addClass("currentMenu").removeClass("hideChildren"); } MenuTree.prototype.freshTag = function($e){ //處理點擊的元素 this.changeCurNode($e); //將綁定在元素上的url取出 var url = $e.attr("url"); if(url.indexOf("http")==0 ){ window.open(url); return; } //這個會在下一篇文章再講,這裏是創建右側mybar和url頁面的顯示信息 myBar.freshTag($e.attr("id"),$e.html(),url); } 

    3、JSP頁面的調用

    JSP頁面很簡單,創建一個左側容器id為“leftTree”,然後:

var leftTree = new MenuTree("leftTree","<c:url value=‘/menu/getMenuTree‘/>");

    我說明一下,這篇文章只是講解左側菜單的讀取和創建,至於點擊顯示對應頁面準備在下一篇文章介紹。

    4、後臺的處理過程    

package cn.wangze.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import cn.wangze.service.SysCacheService;
import cn.wangze.service.SysMenuService;

import cn.wangze.domain.SysMenu;
//import cn.wangze.service.SysMenuService;
//import cn.wangze.utils.AuthUtils;

@Controller
@RequestMapping("/menu")
@SessionAttributes("sysUser") 
public class SysMenuController01 extends BaseController{
    Log log = LogFactory.getLog(getClass());
    
    //將菜單的service註入控制器裏面
    @Resource
    private SysMenuService<SysMenu> sysMenuService;
    //若菜單固定的話,我們可以將數據放到緩存中,這樣不用每次都從數據庫請求
    @Autowired
    private SysCacheService sysCacheService;
    
    @RequestMapping(value = "/{pagePath}/{pageName}")
    public String goMenuPage(@PathVariable String pagePath, @PathVariable String pageName,HttpServletRequest request) {
        setFromURI(request);
        return "/" + pagePath + "/" + pageName;
    }
    
    @RequestMapping(value = "/getMenuTree")
    public void getMenu(HttpServletResponse response,HttpSession session) {
        //調用sysCacheService的queryMenuList方法來取數據
        List<SysMenu> list = sysCacheService.queryMenuList();
        log.debug("總菜單:" + list);
        if (list == null) return;
        //可參照我前面發的博客文章,封裝的返回數據的方法,在BaseController裏面
        sendJsonList(list, response);
    }
}

    Service和Domain層還有Mapper層的代碼我就不發了,就是查詢的操作,因為沒有涉及到角色權限的控制,所以沒有多大的難度。

  5、創建好之後的效果

技術分享

   

  下一篇文章我們講解點擊子菜單,右側顯示對應地址的過程。

JavaScript處理數據完成左側二級菜單的搭建