MVC3快速搭建Web應用(四)功能菜單


這一篇我們來打造一個手風琴試的功能菜單,雖然不能像之前那些一樣完全自動生成,但這個模塊是一個通用模塊,完全可以在之后的項目中復用。

1.數據庫准備

打開RapidWebDevSample.pdm,添加表T_FunctionType如下:

拷貝Preview中的SQL語句在查詢器中執行。

手工錄入幾條數據,注意其中父編號的對應關系。本項目中由於使用手風琴式功能菜單,程序代碼沒有考慮2級以上的問題,但是數據庫是支持無限級別的。

IconStyle是功能菜單上對應圖標樣式名稱,例如css中是:

.m-planapprove{ background: url('icons/planapprove.png') no-repeat center;}

那么你的IconStyle應該填寫m-planapprove,Url是對應於網站根目錄的路徑,比如User/Index

數據庫准備好后,我們要做的第一件事是更新edmx文件,將表勾選添加。

2.生成功能樹

為了生成功能樹我們當然需要一個C#的數據結構來容納:

    /// <summary>
    /// 菜單項模型
    /// </summary>
    public class MenuItem
    {
        public int menuid { get; set; }
        public string menuname { get; set; }
        public string icon { get; set; }
        public string url { get; set; }
        public int index { get; set; }
        public List<MenuItem> menus{ get; set; }
    }

根據數據庫生成功能菜單,只寫了兩層,當然你也可以為你的無限級別菜單改寫成遞歸,以下代碼看起來可能有些地方會比較怪,因為為了做這個例子我把權限控制剝離了出去並沒有好好重構代碼。

提示:需要權限控制的可以在這里添加過濾,我的邏輯是:傳遞一個userid,獲取該用戶的所有權限,判斷如果用戶擁有這個菜單權限則添加到items里,否則跳過。

     /// <summary>
        /// 支持兩層
        /// </summary>
        /// <returns></returns>
        public static List<MenuItem> GetFunctionMenus()
        {
            List<MenuItem> items = new List<MenuItem>();
            using (RapidWebDevSampleEntities bse = new RapidWebDevSampleEntities())
            {
                //加載第一層
                List<T_FunctionType> list = bse.T_FunctionType.Where(p => p.ParentFunctionTypeID == 0 && p.Visible == 1).OrderBy(f => f.Index).ToList();
                //加載所有
                List<T_FunctionType> all = bse.T_FunctionType.Where(p => p.Visible == 1).OrderBy(f => f.Index).ToList();

                //循環加載第一層
                foreach (var functionType in list)
                {
                    MenuItem mi = new MenuItem()
                                  {icon = functionType.IconStyle, menuid = functionType.FunctionTypeID, menuname = functionType.FunctionTypeName, url = functionType.Url};
                        //從all中加載自己的子菜單
                        List<T_FunctionType> subs = all.Where(p => p.ParentFunctionTypeID == mi.menuid).OrderBy(f => f.Index).ToList();
                        //如果有
                        if (subs.Any())
                        {
                            List<MenuItem> subitems = new List<MenuItem>();
                            //循環添加子菜單
                            foreach (var subtype in subs)
                            {
                                MenuItem submi = new MenuItem() {icon = subtype.IconStyle, menuid = subtype.FunctionTypeID, menuname = subtype.FunctionTypeName, url = subtype.Url};

                                subitems.Add(submi);
                            }
                            mi.menus = subitems;
                        }
                        items.Add(mi);
                    }
            }
            return items;
        }
    }

3.界面表現

首先,我們添加一個Home控制器,里面包含3個Action,其中Default是默認添加的tab主頁,Nav是功能菜單的分部視圖,Index是我們真正的首頁,都非常簡單地返回對應視圖。

        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Nav()
        {
            return View();
        }
        public ActionResult Default()
        {
            return View();
        }

主頁代碼主要是對tab進行支持,添加tab與創建frame的js:

    function addTab(subtitle, url, closable) {
        if (!$('#tabs').tabs('exists', subtitle)) {
            var cl = true;
            if (closable == 'false')
                cl = false;
            $('#tabs').tabs('add', {
                title: subtitle,
                content: createFrame(url),
                closable: cl
            });
        } else {
            $('#tabs').tabs('select', subtitle);
        }
    }

  function createFrame(url) {
        var s = '<iframe scrolling="auto" frameborder="0"  src="' + url + '" style="width:100%;height:99.5%"></iframe>';
        return s;
    }

主頁中調用分部視圖nav時,傳遞了一個List<MenuItem>對象,也就是GetFunctionMenus的返回值:

    <div region="west" split="true" title="功能菜單" style="width: 280px; padding: 1px; overflow: hidden;">
        @{
            Html.RenderPartial("Nav", FunctionMenu.GetFunctionMenus());
        }
    </div>

功能菜單的關鍵在於Nav中,這是一個強類型的分部視圖,他接收來自主頁的List<MenuItem>,根據menus生成html。

@model List<RapidWebDevSample.Common.MenuItem>
@{
    Layout = null;
}
<div id="nav" class="easyui-accordion" fit="true" border="false">
@foreach(var menu in Model)
{
    <div title=" @menu.menuname" iconCls="menuItem @menu.icon" >
            @if (menu.menus != null)
            {
                <ul>

                    @foreach (var submenu in menu.menus)
                    {
                        string menuid = "menu"+submenu.menuid;
                        <li><div><a ref="@menu.menuname" href="#" rel='@submenu.url' id="@menuid"><span class="@submenu.icon" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">@submenu.menuname</span></a></div></li>
                    }
            
                </ul>
            }
    </div>
}
    </div>

它最終生成的代碼類似於:

 <div title=" 工單管理" iconCls="menuItem mi m-task" >
                <ul>

                        <li><div><a ref="工單管理" href="#" rel='Task/ReciveIndex' id="menu39"><span class="mmi m-recivebox" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">工單收件箱</span></a></div></li>
                        <li><div><a ref="工單管理" href="#" rel='Task/SendIndex' id="menu48"><span class="mmi m-sendbox" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">工單發件箱</span></a></div></li>
                        <li><div><a ref="工單管理" href="#" rel='Task/ApproveIndex' id="menu70"><span class="mmi m-approvebox" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">工單審核箱</span></a></div></li>
                        <li><div><a ref="工單管理" href="#" rel='PlanManage' id="menu79"><span class="mmi m-plan" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">計划管理</span></a></div></li>
                        <li><div><a ref="工單管理" href="#" rel='PlanManage/ApproverIndex' id="menu80"><span class="mmi m-planapprove" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">計划審核</span></a></div></li>
                        <li><div><a ref="工單管理" href="#" rel='TaskReport' id="menu94"><span class="" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">工單報表</span></a></div></li>
                        <li><div><a ref="工單管理" href="#" rel='WeeklyReport' id="menu95"><span class="" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">周報表</span></a></div></li>
            
                </ul>
    </div>
    <div title=" 系統管理" iconCls="menuItem mi m-sys" >
                <ul>

                        <li><div><a ref="系統管理" href="#" rel='Department' id="menu15"><span class="mi m-dep" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">組織機構</span></a></div></li>
                        <li><div><a ref="系統管理" href="#" rel='User' id="menu5"><span class="mi m-users" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">用戶管理</span></a></div></li>
                        <li><div><a ref="系統管理" href="#" rel='Role' id="menu4"><span class="mi m-role" >&nbsp;</span>&nbsp;&nbsp;<span class="nav">角色設置</span></a></div></li>
            
                </ul>
    </div>

好了,差不多了,再給這個手風琴加上點效果,打開Content中的Site.css,在最底下添加:

.easyui-accordion ul{list-style-type:none;margin:0px; padding:10px;}
.easyui-accordion ul li{ padding:0px;}
.easyui-accordion ul li a{line-height:24px;}
.easyui-accordion ul li div{margin:2px 0px;padding-left:10px;padding-top:2px;}
.easyui-accordion ul li div.hover{border:1px dashed #99BBE8; background:#E0ECFF;cursor:pointer;}
.easyui-accordion ul li div.hover a{color:#416AA3;}
.easyui-accordion ul li div.selected{border:1px solid #99BBE8; background:#E0ECFF;cursor:default;}
.easyui-accordion ul li div.selected a{color:#416AA3; font-weight:bold;}

最終效果應該是這樣的:

本示例提供下載:點我

測試數據庫下載:點我


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM