• 运用递归生成多级菜单栏


    1:还是先上图 (出于保密原因,这里数据需要涂鸦,请谅解)

    可以看到 红箭头所指的进度条显示的是菜单栏竖向的进度,本例中我所有的子菜单一共有300多个 但是大的分类只有6个 

     那我们开发的时候是不是要一个个在前端写好呢?这未免太恐怖也太可怕,加入我们的菜单要添加一个呢 换起来也麻烦。

    所以正确的做法是菜单从数据库中读取。

    2:下面就来展示下数据库的结构 这里我只要显示3个字段  id(当前菜单的id 是newid())、pid(当前菜单的父级id)、name(当前菜单的内容)

      在mvc中我微菜单生成专门写了个方法    

    在这个方法里从数据库中查询出符合条件的菜单集合

    方法体 如下   

    public ActionResult Navigator2()
    {
    CheckAuth();
    try
    {
    if (m_user == null)
    {
    throw new Exception();
    }
    IList<Menu> li2 = new List<Menu>();
    if (Session["Navigator2"] != null)  //将菜单存到session中
    {
    li2 = Session["Navigator2"] as IList<Menu>;
    }
    else
    {
    string strSql = @" sql 根据自己情况去定";

    DBHelper db = new DBHelper(Constant.db);
    DataTable dt = db.GetDataSet(strSql);
    if (dt != null && dt.Rows.Count > 0)
    {
    li2 = JsonConvert.DeserializeObject<IList<Menu>>(JsonConvert.SerializeObject(dt));
    Session["Navigator2"] = li2;
    }
    }

    ViewBag.data = li2;
    }
    catch (Exception ex)
    {
    ViewBag.data = null;
    }

    ViewBag.tage = 2;
    return View("~/Views/Shared/Navigator2.cshtml");
    }

    navigator中 有如下代码

    @{ if (ViewBag.tage == 1)//以为我还有个 Navigator方法 这里用的是 Navigator2 是下面 ViewBag.tage == 2 的方法体
    {
    @Navigator2.Sys_Menu(ViewBag.data, null, 0);
    }
    if (ViewBag.tage == 2)
    {
    @Navigator2.Sys_Menu2(ViewBag.data, "0d7e7ece-8b18-4d63-876b-edad20d29ca2", 0);
    }

    }

    在appcode文件夹中有个 Navigator2

    里面递归调用方法体如下 

    @using app.DA.ef

    @helper Sys_Menu2(IEnumerable<app.ViewModel.Menu> entities, string pid, int? Plv)
    {
    string cls = "";
    string Liclass = "";
    string iclass = "";

    //@Navigator2.Sys_Menu(@ViewBag.data, null,0)第一次调用是传递的pid是null 这里调用给出一级菜单的id作为二级菜单的父id
    //筛选出一级菜单 entity是所有一级菜单的实体
    //将所有的数据集合entities传递过去由entity.id作为条件筛选 会筛选出所有符合要求的下一级菜单所需要的集合 这里不要传递第一个参数不要传递entity 否则共筛选的数据源会越来越小 不符合要求
    //第三个参数传递0表示是第一级菜单,下面会有判断if(Plv > 0) 代表是子节点 去找根,否则父空 为根节点 再具体渲染ul li

    if (entities != null)//实体不为空开始循环
    {

    if (Plv == 0)
    {
    cls = "main-menu";
    Liclass = "active opened active";
    iclass = "linecons-cog";
    }
    if (Plv == 1)
    {
    cls = "";
    Liclass = "";
    iclass = "entypo-flow-line";
    }
    if (Plv == 2)
    {
    cls = "";
    Liclass = "";
    iclass = "entypo-flow-parallel";
    }
    if (Plv == 3)
    {
    cls = "";
    Liclass = "";
    iclass = "entypo-flow-cascade";
    }
    if (Plv == 4)
    {
    cls = "";
    Liclass = "";
    iclass = "entypo-flow-branch";
    }
    //var entity = entities.Where(o => o.lvl == 3);
    IEnumerable<app.ViewModel.Menu> menu;
    menu = entities.Where(o => o._parentId == pid);
    Plv++;
    if (menu.Count() > 0)//判断是否有孩子节点 有则继续进行递归 没有不作任何处理
    {
    //渲染孩子
    <ul id='@cls' class='@cls'>
    @foreach (var item in menu)//根据id寻找子节点
    {
    <li class='@Liclass'>
    <a href="javascript:void(0)" onclick="onNodeclickNav(this)" ondblclick="onNodeDblclickNav(this)" name="@item.name" url="@item.url" id="@item.id">
    <i class='@iclass'></i>
    <span class="title">@item.name</span>
    </a>
    @Sys_Menu2(entities, item.id, Plv) @*这里将item.id作为筛选条件*@
    </li>
    }
    </ul>
    }
    }
    }

    在页面加载时请求运行此方法之后 就会展示菜单,如果有新添加的菜单只需要在数据库中添加即可,退出清除session知乎再刷新就能看到最新的效果

    主题思想就是菜单表里面各级菜单用 id  和pid联系起来 父级菜单的id为自己菜单的pid。

    分享、奉献、勤奋、好学
  • 相关阅读:
    生成器
    迭代器
    闭包函数
    装饰器(2)
    装饰器(1)
    名称空间与作用域(2)
    110.网络编程-mail
    109.网络编程-FTP
    108.网络编程-TCP/UDP
    107.xpath
  • 原文地址:https://www.cnblogs.com/zzlblog/p/5084907.html
Copyright © 2020-2023  润新知