基于MVC4+EasyUI的Web开发框架经验计算(三)- 使用Json实体类创设菜单数据

不久前花了无数小时在重构和尤其提炼小编的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持壹致,而在Web上,我第叁选择EasyUI的前端界面处理技术,走MVC的技术途径,在重构完善进程中,很多细节费用不少光阴开始展览商讨和提纯,一步步走过来,也积累了不少经验,本类别将重视介绍自个儿在一发健全本人的Web框架基础上积累的阅历进行分享,本散文重要介绍使用什么使用Json实体类创设菜单数据,然后在主界面中进行利用。

 菜单的界面效果如下所示,菜单分为顶尖菜单、二级菜单、三级菜单,他们各自在岗位上是分裂的定义,这些界面布局规定三级菜单正是细微的菜系节点了,相当于纸牌节点。

图片 1

要兑现以上的食谱,供给把菜单定义成相关的Json数据,然后经过脚本把它们拉长到界面里面去,如下数据宁海平调本就是概念相关的菜周全据的。

    <script type="text/javascript">
        var _menus = {
            "default": [
                {
                    "menuid": "1", "icon": "icon-computer", "menuname": "权限管理",
                    "menus": [
                              { "menuid": "13", "menuname": "用户管理", "icon": "icon-user", "url": "/User/Index" },
                              { "menuid": "14", "menuname": "组织机构管理", "icon": "icon-organ", "url": "/OU/Index" },
                              { "menuid": "15", "menuname": "角色管理", "icon": "icon-group-key", "url": "/Role/Index" },
                              { "menuid": "16", "menuname": "功能管理", "icon": "icon-key", "url": "/Function/Index" },
                              { "menuid": "17", "menuname": "登陆日志", "icon": "icon-view", "url": "/LoginLog/Index" }
                    ]
                },
               {
                   "menuid": "2", "icon": "icon-user", "menuname": "其他管理",
                   "menus": [{ "menuid": "21", "menuname": "修改密码", "icon": "icon-lock", "url": "javascript:ShowPasswordDialog()" }
                   ]
               }
            ],
            "point": [
                {
                    "menuid": "3", "icon": "icon-computer", "menuname": "事务中心",
                    "menus": [
                              { "menuid": "33", "menuname": "测试菜单1", "icon": "icon-user", "url": "../Commonpage/building.htm" },
                              { "menuid": "34", "menuname": "测试菜单2", "icon": "icon-organ", "url": "../Commonpage/building.htm" },
                              { "menuid": "35", "menuname": "测试菜单3", "icon": "icon-group-key", "url": "../Commonpage/building.htm" },
                              { "menuid": "36", "menuname": "测试菜单4", "icon": "icon-key", "url": "../Commonpage/building.htm" }
                    ]
                },
                {
                    "menuid": "4", "icon": "icon-user", "menuname": "其他菜单",
                    "menus": [{ "menuid": "41", "menuname": "测试菜单5", "icon": "icon-lock", "url": "../Commonpage/building.htm" }]
                }
            ]
        };

        function showSubMenu(url, title, menuCategory, defaultIcon) {
            if (defaultIcon == null || defaultIcon == "") {
                defaultIcon = "icon-table";
            }
            addTab(title, url, "icon " + defaultIcon);
            Clearnav();
            if (menuCategory != "") {
                addNav(_menus[menuCategory]);
            }
        }
    </script>

从地点的菜单Json数据来看,它是三个字典的Json数据列表,在Web界面上,通过上边包车型地铁代码能够开始展览上边Json定义的二级菜单。

<li><a href="#" onclick="showSubMenu('/User/Index', '用户管理', 'default')">权限管理</a></li>

图片 2

尽管上边包车型客车定义的数量可知消除菜单的展示难题,可是对于大家必要动态控制的菜谱,明显做不到,由此供给把上边的json数据,通过菜单控制器进行动态生成才能够,然后在本子里面通过Jquery的不二等秘书诀获得Json数据,如下所示。

        var _menus = {};
        //同步获取
        $.ajax({
            type: 'GET',
            url: '/Menu/GetMenuData?r=' + Math.random(),
            async: false,//同步
            dataType: 'json',
            success: function (json) {
                _menus = json;
            },
            error: function (xhr, status, error) {
                alert("操作失败"); //xhr.responseText
            }
        });

地点的GetMenuData方法,通过后台的控制器实行动态变化的,它的代码如下所示

        /// <summary>
        /// 获取树形展示数据
        /// </summary>
        /// <returns></returns>
        public ActionResult GetMenuData()
        {
            string json = GetTreeJson("-1", "", "");
            json = json.Trim(',');
            return Content(string.Format("[{0}]", json));
        }

        /// <summary>
        /// 递归获取树形信息
        /// </summary>
        /// <returns></returns>
        private string GetTreeJson(string PID, string folderIcon, string leafIcon)
        {
            string condition = string.Format("PID='{0}' ", PID);
            List<MenuInfo> nodeList = BLLFactory<Menu>.Instance.Find(condition);
            StringBuilder content = new StringBuilder();
            foreach (MenuInfo model in nodeList)
            {
                string ParentID = (model.PID == "-1" ? "0" : model.PID);
                string subMenu = this.GetTreeJson(model.ID, folderIcon, leafIcon);
                string parentMenu = string.Format("{{ \"id\":\"{0}\", \"pId\":\"{1}\", \"name\":\"{2}\" ", model.ID, ParentID, model.Name);
                if (string.IsNullOrEmpty(subMenu))
                {
                    if (!string.IsNullOrEmpty(leafIcon))
                    {
                        parentMenu += string.Format(",\"icon\":\"{0}\" }},", leafIcon);
                    }
                    else
                    {
                        parentMenu += "},";
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(folderIcon))
                    {
                        parentMenu += string.Format(",\"icon\":\"{0}\" }},", folderIcon);
                    }
                    else
                    {
                        parentMenu += "},";
                    }
                }

                content.AppendLine(parentMenu.Trim());
                content.AppendLine(subMenu.Trim());
            }
            return content.ToString().Trim();
        }

而是对于地点的代码,小编以为纵然能一举成功难点,能够正确生成相关的Json代码,但是觉得不够优雅,小编不希罕使用拼凑方法创设数据。

前边看了Menu的Json脚本,作者说过她是3个字典类型的Json数据格式,那么大家是还是不是能够透过字典和实体音信来承载,然后径直通过ToJson方法出来吗?答案是能够的。

        /// <summary>
        /// 获取菜单的树形展示数据
        /// </summary>
        /// <returns></returns>
        public ActionResult GetMenuData()
        {
            Dictionary<string, List<MenuData>> dict = new Dictionary<string, List<MenuData>>();

            List<MenuInfo> list = BLLFactory<Menu>.Instance.GetTopMenu(MyConstants.SystemType);
            int i = 0;
            foreach (MenuInfo info in list)
            {
                if (!HasFunction(info.FunctionId))
                {
                    continue;
                }              
                List<MenuData> treeList = new List<MenuData>();
                List<MenuNodeInfo> nodeList = BLLFactory<Menu>.Instance.GetTreeByID(info.ID);
                foreach (MenuNodeInfo nodeInfo in nodeList)
                {
                    if (!HasFunction(nodeInfo.FunctionId))
                    {
                        continue;
                    }                                                                                                                                                                       
                    MenuData menuData = new MenuData(nodeInfo.ID, nodeInfo.Name, string.IsNullOrEmpty(nodeInfo.WebIcon) ? "icon-computer" : nodeInfo.WebIcon);
                    foreach (MenuNodeInfo subNodeInfo in nodeInfo.Children)
                    {
                        if (!HasFunction(subNodeInfo.FunctionId))
                        {
                            continue;
                        }
                        string icon = string.IsNullOrEmpty(subNodeInfo.WebIcon) ? "icon-organ" : subNodeInfo.WebIcon;
                        menuData.menus.Add(new MenuData(subNodeInfo.ID, subNodeInfo.Name, icon, subNodeInfo.Url));
                    }
                    treeList.Add(menuData);
                }

                //添加到字典里面,如果是第一个,默认用default名称
                string dictName = (i++ == 0) ? "default" : info.ID;
                dict.Add(dictName, treeList);
            }

            string content = ToJson(dict);
            return Content(content.Trim(','));
        }

上面的代码,通过MenuData的目的数据,来承载相关的菜系音信,然后把它添加到字典Dictionary<string,
List<MenuData>> dict
里面就足以了,那样的代码,未有那么多拼凑出来的感觉,是还是不是很为难啊?把指标转换为Json数据,直接通过ToJson就能够解决了,非常粗略吗。

而菜单的权位控制,正是经过聚合权限管理举行判断,父菜单假使没有权限,就一直跳过,不在继续生成上面包车型客车子菜单,权限判断的如下所示。

if (!HasFunction(info.FunctionId))
{
       continue;
 } 

当然,在界面上进展二级菜单的操作界面,也应当经过脚本动态进展转变的,那样才能不蔓不枝全部的剧情动态构建。

        <ul class="navigation" style="display:block">
            @Html.Raw(@ViewBag.HeaderScript)</ul>

上面使用ViewBag对象开展传递脚本内容到界面上,其实后台湾学生成的操作,是单排HTML代码正是了,代码类似下边包车型大巴情节。

<li><a href="#" onclick="showSubMenu('/User/Index', '用户管理', 'default')">权限管理</a></li>

末段出来的意义,便是博客开首介绍的界面截图,未有任何变化,但是代码我们早就经过了几步的优化整治,看起来很清爽,更能完成动态变化了。

图片 3

 

没事能够回顾下别的两篇的经验计算内容:

基于MVC四+EasyUI的Web开发框架的俯十就是文章:

依据MVC4+EasyUI的Web开发框架形成之旅–总体介绍

依照MVC4+EasyUI的Web开发框架形成之旅–MVC控制器的规划

依据MVC四+EasyUI的Web开发框架形成之旅–界面控件的应用

听别人说MVC肆+EasyUI的Web开发框架形成之旅–附属类小部件上传组件uploadify的施用

据说MVC四+EasyUI的Web开发框架形成之旅–框架总体界面介绍

基于MVC4+EasyUI的Web开发框架形成之旅–基类控制器CRUD的操作

依照MVC4+EasyUI的Web开发框架形成之旅–权限决定

依照MVC肆+EasyUI的Web开发框架经验总计(壹)-利用jQuery Tags Input
插件突显选拔记录

依照MVC4+EasyUI的Web开发框架经验总结(2)-
使用EasyUI的树控件营造Web界面

听别人讲MVC四+EasyUI的Web开发框架经验计算(叁)-
使用Json实体类创设菜单数据

听新闻说MVC四+EasyUI的Web开发框架经验计算(4)–使用图表控件Highcharts

基于MVC4+EasyUI的Web开发框架经验总括(5)–使用HTML编辑控件CKEditor和CKFinder

基于MVC4+EasyUI的Web开发框架经验计算(陆)–在页面中采纳下拉列表的拍卖

基于MVC4+EasyUI的Web开发框架经验总计(7)–完毕省份、城市、行政区3者联合浮动

基于MVC4+EasyUI的Web开发框架经验总括(捌)–达成Office文书档案的预览

遵照MVC肆+EasyUI的Web开发框架经验总计(玖)–在Datagrid里面完毕外键字段的转义操作

遵照MVC四+EasyUI的Web开发框架经验计算(十)–在Web界面上落实数据的导入和导出

依据MVC四+EasyUI的Web开发框架经验计算(1一)–使用Bundles处理简化页面代码

依照MVC四+EasyUI的Web开发框架经验总计(1二)–利用Jquery处理多少交互的两种艺术

依照MVC四+EasyUI的Web开发框架经验总括(一3)–DataGrid控件完成活动适应宽带中度

依据MVC4+EasyUI的Web开发框架经验总括(14)–自动生成图标准样品式文件和图标的挑选操作