C#——后台管理端多级菜单的生成方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mzl87/article/details/84455095

现在大多的应用程序(后端)都有菜单,不管是在左侧还是上面,界面基本都是基于现有的UI框架或者网上找的单独的菜单的插件。而实现的方式,大部分都是使用的AJAX形式来完成。前段时间,在总结一些过往的项目时,发现了一些不同的实现的方式,这里想总结一下。所以也就有了这篇文章~~

我建立的测试Demo是使用的MVC的模式,菜单是使用的网上找的第三方插件,实现多级(无限)的顶部菜单。直接上代码来说明~

开始之前,先看下css和js的引用情况以及一些需要的准备工作:

css

<link href="~/scripts/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" href="~/scripts/css/font-awesome.min.css" media="screen">
<link rel="stylesheet" href="~/scripts/css/zlight.menu.css" media="screen">

js

<script src="~/scripts/jquery-1.9.1.min.js"></script>
<script src="~/scripts/bootstrap.min.js"></script>
<script src="~/scripts/jquery.zlight.menu.1.0.min.js"></script>
<!--自定义的js,编写自己的js生成菜单-->
<script src="~/scripts/Home/home.js"></script>

模拟的数据源

        /// <summary>
        /// 得到数据源
        /// </summary>
        /// <returns></returns>
        private List<MenuModel> GetData()
        {
            var lstData = new List<MenuModel>();
            //顶层菜单
            lstData.Add(new MenuModel() { Id = "1", MenuName = "Blog", MenuUrl = "#", ParentId = "#", SortNumb = 1 });
            lstData.Add(new MenuModel() { Id = "2", MenuName = "Portfolio", MenuUrl = "#", ParentId = "#", SortNumb = 2 });
            lstData.Add(new MenuModel() { Id = "3", MenuName = "Pages", MenuUrl = "#", ParentId = "#", SortNumb = 3 });
            lstData.Add(new MenuModel() { Id = "4", MenuName = "Contact", MenuUrl = "#", ParentId = "#", SortNumb = 4 });
            lstData.Add(new MenuModel() { Id = "5", MenuName = "About", MenuUrl = "#", ParentId = "#", SortNumb = 5 });
            //第二层
            lstData.Add(new MenuModel() { Id = "11", MenuName = "LINK1", MenuUrl = "#", ParentId = "1", SortNumb = 1 });
            lstData.Add(new MenuModel() { Id = "12", MenuName = "LINK2", MenuUrl = "#", ParentId = "1", SortNumb = 2 });
            lstData.Add(new MenuModel() { Id = "13", MenuName = "LINK3", MenuUrl = "#", ParentId = "1", SortNumb = 3 });

            lstData.Add(new MenuModel() { Id = "31", MenuName = "LINK1", MenuUrl = "#", ParentId = "3", SortNumb = 1 });
            lstData.Add(new MenuModel() { Id = "32", MenuName = "DROPDOWN", MenuUrl = "#", ParentId = "3", SortNumb = 2 });
            lstData.Add(new MenuModel() { Id = "33", MenuName = "LINK2", MenuUrl = "#", ParentId = "3", SortNumb = 3 });
            //第三层
            lstData.Add(new MenuModel() { Id = "321", MenuName = "LINK1", MenuUrl = "#", ParentId = "32", SortNumb = 1 });
            lstData.Add(new MenuModel() { Id = "322", MenuName = "LINK2", MenuUrl = "#", ParentId = "32", SortNumb = 2 });
            lstData.Add(new MenuModel() { Id = "323", MenuName = "LINK3", MenuUrl = "#", ParentId = "32", SortNumb = 3 });
            lstData.Add(new MenuModel() { Id = "324", MenuName = "DROPDOWN", MenuUrl = "#", ParentId = "32", SortNumb = 4 });
            //第四层
            lstData.Add(new MenuModel() { Id = "3241", MenuName = "LINK1", MenuUrl = "#", ParentId = "324", SortNumb = 1 });
            lstData.Add(new MenuModel() { Id = "3242", MenuName = "LINK2", MenuUrl = "#", ParentId = "324", SortNumb = 2 });


            return lstData;
        }

后台菜单实现需要的方法

        /// <summary>
        /// 生成菜单拼接字符串
        /// </summary>
        /// <returns></returns>
        private string GenerateMenu()
        {
            StringBuilder sb = new StringBuilder();
            var lstAll = GetData();
            var lstParent = lstAll.FindAll(x => x.ParentId == "#").ToList();
            var lstChilds = lstAll.FindAll(x => x.ParentId != "#").ToList();

            if (lstParent.Any())
            {
                foreach (var top in lstParent)
                {
                    var lstOnes = lstChilds.FindAll(x => x.ParentId == top.Id).OrderBy(x => x.SortNumb).ToList();
                    if (lstOnes.Any())
                    {
                        sb.Append("<li class=\"zlight-dropdown\">")
                            .AppendFormat("<a href = \"{0} \"> {1}<i class=\"icon-angle-down\"></i></a>", top.MenuUrl, top.MenuName)
                            .Append("<ul class=\"zlight-submenu\">");
                        GetChild(sb, lstChilds, lstOnes);
                        sb.Append("</ul></li > ");
                    }
                    else
                    {
                        sb.AppendFormat("<li><a href = \"{0} \"> {1} </a></li>", top.MenuUrl, top.MenuName);
                    }
                }
            }

            return sb.ToString();
        }

        /// <summary>
        /// 得到子菜单项
        /// </summary>
        /// <param name="sb">StrignBuilder对象</param>
        /// <param name="lstChilds">所有子节点集合</param>
        /// <param name="lstOnes">“父”节点集合</param>
        private static void GetChild(StringBuilder sb, List<MenuModel> lstChilds, List<MenuModel> lstOnes)
        {
            foreach (var chld in lstOnes)
            {
                var lstTwos = lstChilds.FindAll(x => x.ParentId == chld.Id).OrderBy(x => x.SortNumb).ToList();
                if (lstTwos.Any())
                {
                    sb.Append("<li class=\"zlight-dropdown\">")
                           .AppendFormat("<a href = \"{0} \"> {1}<i class=\"icon-angle-down\"></i></a>", chld.MenuUrl, chld.MenuName)
                           .Append(" <ul class=\"zlight-submenu\">");
                    GetChild(sb, lstChilds, lstTwos);
                    sb.Append("</ul></li> ");
                }
                else
                {
                    sb.AppendFormat("<li><a href = \"{0} \" target = \"_blank\"> {1} </a></li>", chld.MenuUrl, chld.MenuName);
                }
            }
        }

1、Ajax方式

html部分

<div class="row">
    <div class="col-lg-12">
        <h4>第一种(AJAX):</h4>
    </div>
 </div>

<div class="row">
   <div class="col-lg-12">
       <nav id="zlight-nav">
            <ul id="zlight-main-nav">
                <li class="zlight-active"><a href="/">Home</a></li>
            </ul>
            <!-- MOBILE NAV -->
            <div id="zlight-mobile-nav">
                 <span>Menu</span>
                 <i class="icon-reorder zlight-icon"></i>
                 <select></select>
            </div>
       </nav> <!-- nav close -->
   </div>
</div>

js(注意放到页面加载完成事件中)

$.ajax({
        url: "/Home/GetTopMenu",
        type: 'POST',
        async: false,
        dataType: 'text',
        timeout: 20000,
        error: function () {
            alert('Error loading XML document');
        },
        success: function (result) {
            $("#zlight-main-nav").append(result);
            $('#zlight-nav').zlightMenu();
        }
    });

后台的Action方法

[HttpPost]
public ActionResult GetTopMenu()
{
    return Content(GenerateMenu());
}

2、ViewBag方式

html部分

        <div class="row">
            <div class="col-lg-12">
                <h4>第二种(ViewBag):</h4>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-12">
                <nav id="zlight-nav" class="razer">
                    <ul id="zlight-main-nav">
                        <li class="zlight-active"><a href="/">Home</a></li>
                        @Html.Raw(@ViewBag.TopMenu)
                    </ul>
                    <!-- MOBILE NAV -->
                    <div id="zlight-mobile-nav">
                        <span>Menu</span>
                        <i class="icon-reorder zlight-icon"></i>
                        <select></select>
                    </div>
                </nav>
            </div>
        </div>

js

$('.razer').zlightMenu();

后台代码

// GET: Home
public ActionResult Index()
{
     ViewBag.TopMenu = GenerateMenu();

     return View();
}

3、Razer递归方式(很少用)

html部分

        <div class="row">
            <div class="col-lg-12">
                <h4>第三种(Razer递归):</h4>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-12">
                <nav id="zlight-nav" class="razerdigui">
                    <ul id="zlight-main-nav">
                        <li class="zlight-active"><a href="/">Home</a></li>
                        @{
                            var lstData = ViewBag.MenuDataList as List<MenuModel>;
                            @helper DisplayChildMenu(List<MenuModel> lstChilds, List<MenuModel> lstOnes)
                            {
foreach (var chld in lstOnes)
{
    var lstTwos = lstChilds.FindAll(x => x.ParentId == chld.Id).OrderBy(x => x.SortNumb).ToList();
    if (lstTwos.Any())
    {
            <li class="zlight-dropdown">
                <a href="@chld.MenuUrl" target="_blank">@chld.MenuName <i class="icon-angle-down"></i></a>
                <ul class="zlight-submenu">
                    @DisplayChildMenu(lstChilds, lstTwos)
                </ul>
            </li>
    }
    else
    {
            <li><a href="@chld.MenuUrl" target="_blank">@chld.MenuName</a></li>
    }
}
}
                            var lstParent = lstData.FindAll(x => x.ParentId == "#").ToList();
                            var lstChilds = lstData.FindAll(x => x.ParentId != "#").ToList();
                            if (lstParent.Any())
                            {
                                foreach (var top in lstParent)
                                {
                                    var lstOnes = lstChilds.FindAll(x => x.ParentId == top.Id).OrderBy(x => x.SortNumb).ToList();
                                    if (lstOnes.Any())
                                    {
                                        <li class="zlight-dropdown">
                                            <a href="@top.MenuUrl">@top.MenuName <i class="icon-angle-down"></i></a>
                                            <ul class="zlight-submenu">
                                                @DisplayChildMenu(lstChilds, lstOnes)
                                            </ul>
                                        </li>
                                    }
                                    else
                                    {
                                        <li><a href="@top.MenuUrl">@top.MenuName</a></li>
                                    }
                                }
                            }
                        }
                    </ul>
                    <!-- MOBILE NAV -->
                    <div id="zlight-mobile-nav">
                        <span>Menu</span>
                        <i class="icon-reorder zlight-icon"></i>
                        <select></select>
                    </div>
                </nav>
     
            </div>
        </div>

js部分

$('.razerdigui').zlightMenu();

后台部分

// GET: Home
public ActionResult Index()
{
    ViewBag.MenuDataList = GetData();

    return View();
}

后记:在非MVC模式下,第一中Ajax方式是非常常用的,即使在MVC模式下仍常用。第二种和第三中在MVC模式下用都可以,Razer的递归之前并没有注意到,一次突发奇想就度娘了下,结果还真有。至于需要用哪种,看个人吧

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/84455095