zoukankan      html  css  js  c++  java
  • 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="100%;height:99.5%"></iframe>';
            return s;
        }

    主页中调用分部视图nav时,传递了一个List<MenuItem>对象,也就是GetFunctionMenus的返回值:

        <div region="west" split="true" title="功能菜单" style=" 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;}

    最终效果应该是这样的:

    本示例提供下载:点我

    测试数据库下载:点我

    欢迎转载,但请保留链接 http://www.cnblogs.com/limlee --- GeekLion
  • 相关阅读:
    ORA01034:ORACLE not available 问题的解决方法
    利用Bulk Insert将Excel中的大批量数据入库
    【Hibernate】*.hbm.xml配置
    lib和dll文件的区别和联系
    oracle ,mysql总date的比较
    C++ Primer 4 CPP Note 1.5 类的简介
    C++ Primer 4 CPP Note 1.4 控制结构
    未找到方法: Dispose System.IO.Stream
    pragma comment的使用
    C++ Primer 4 CPP Note 2.1 基本内置类型
  • 原文地址:https://www.cnblogs.com/limlee/p/2607655.html
Copyright © 2011-2022 走看看