MVC3快速搭建Web应用(四)功能菜单

这一篇我们来打造一个手风琴试的功能菜单,虽然不能像之前那些一样完全自动生成,但这个模块是一个通用模块,完全可以在之后的项目中复用。

1.数据库准备

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

MVC3快速搭建Web应用(四)功能菜单

拷贝Preview中的SQL语句在查询器中执行。

MVC3快速搭建Web应用(四)功能菜单

手工录入几条数据,注意其中父编号的对应关系。本项目中由于使用手风琴式功能菜单,程序代码没有考虑2级以上的问题,但是数据库是支持无限级别的。

IconStyle是功能菜单上对应图标样式名称,例如css中是:

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

那么你的IconStyle应该填写m-planapprove,Url是对应于网站根目录的路径,比如User/Index

数据库准备好后,我们要做的第一件事是更新edmx文件,将表勾选添加。

MVC3快速搭建Web应用(四)功能菜单

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

最终效果应该是这样的:

MVC3快速搭建Web应用(四)功能菜单

本示例提供下载:点我

测试数据库下载:点我

你可能感兴趣的:(Web应用)