【问题标题】:ASP.Net MVC - One child menu not showingASP.Net MVC - 一个子菜单未显示
【发布时间】:2018-08-24 11:10:35
【问题描述】:

我是初学者程序员。我正在尝试显示层次结构,但未显示一个嵌套子菜单。我想我的逻辑有错误但无法找到。任何人都介意指出一个名为 child 4 的子菜单未在 UI 中显示的区域。

这是代码

public ActionResult Index()
{
    List<MenuItem> mi = new List<MenuItem>
    {
        new MenuItem {Id=1,Name="Parent 1", ParentId=0},
        new MenuItem {Id=2,Name="child 1", ParentId=1},
        new MenuItem {Id=3,Name="child 2", ParentId=1},
        new MenuItem {Id=4,Name="child 3", ParentId=1},
        new MenuItem {Id=5,Name="Parent 2", ParentId=0},
        new MenuItem {Id=6,Name="child 4", ParentId=4}
    };
    ViewBag.menusList = mi;
    return View();
}


public class MenuItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
}

剃刀代码

@{ var menusList = ViewBag.menusList as List<Scaffolding.Controllers.MenuItem>; }

@if (menusList != null)
{
    <ul id="menu">
        @foreach(var parentMenu in menusList.Where(p => p.ParentId == 0))
        {
        <li>
            <span>@parentMenu.Name</span>
            @if (menusList.Count(p => p.ParentId == parentMenu.Id) > 0)
            {
                <ul id="menu">
                    @foreach(var childMenu in menusList.Where(p => p.ParentId == parentMenu.Id))
                    {
                        <li>
                            <span>@childMenu.Name</span>
                        </li>
                    }
                </ul>
            }
        </li>
        }
    </ul>
}

用户界面看起来像

提前致谢。

编辑

我已经更改了代码,现在收到错误调用

CS1502:最佳重载方法匹配 'ASP._Page_Views_Menu_Index_cshtml.ShowTree(System.Collections.Generic.List)' 有一些无效的参数

我的代码仍然无法正常工作。这是更新的代码

剃须刀代码

@{
    var menuList = ViewBag.menusList as List<Scaffolding.Controllers.MenuDTO>;
    ShowTree(menuList);
}


@helper ShowTree(List<Scaffolding.Controllers.MenuDTO> menusList)
{
    if (menusList != null)
    {
        foreach (var item in menusList)
        {
            <li>
                <span>@item.Name</span>
                @if (item.Children.Any())
                {
                    <ul>
                        @ShowTree(item.Children)
                    </ul>
                }
            </li>
        }
    }
}

动作代码

public ActionResult Index()
{
    List<MenuItem> allMenu = new List<MenuItem>
    {
        new MenuItem {Id=1,Name="Parent 1", ParentId=0},
        new MenuItem {Id=2,Name="child 1", ParentId=1},
        new MenuItem {Id=3,Name="child 2", ParentId=1},
        new MenuItem {Id=4,Name="child 3", ParentId=1},
        new MenuItem {Id=5,Name="Parent 2", ParentId=0},
        new MenuItem {Id=6,Name="child 4", ParentId=4}
    };


    List<MenuDTO> mi = allMenu
    .Select(e => new
    {
        Id = e.Id,
        Name = e.Name,
        ParentId = e.ParentId,
        Children = allMenu.Where(x => x.ParentId == e.Id).ToList()
    }).ToList()
    .Select(p => new MenuDTO
    {
        Id = p.Id,
        Name = p.Name,
        ParentId = p.ParentId,
        Children = allMenu.Where(x => x.ParentId == p.Id).ToList()
    }).ToList();

    ViewBag.menusList = mi;

    return View();
}

类代码

public class MenuItem 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public virtual ICollection<MenuItem> Children { get; set; }
}

public class MenuDTO 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public virtual ICollection<MenuItem> Children { get; set; }
}

【问题讨论】:

  • 您有 3 层深度,但只有 2 个嵌套的 foreach 循环。但是使用嵌套的 foreach 循环不是正确的方法(如果你以后有 4 或 5 个级别怎么办)。你需要一个递归函数。
  • 您真的需要一个 3 级菜单,还是只是一个错字?哪个是 Child4 的父母?我只是好奇。
  • @StephenMuecke 是的,你是对的,可能存在第 n 级嵌套。所以需要递归。您会使用适用于第 n 个嵌套结构的递归函数来构造我的代码吗?
  • 如果这是您经常做的事情,并且可能在多个项目中使用,我会考虑使用HtmlHelper 扩展方法(例如参考this answer。否则您可以使用@helper 方法在视图中
  • @StephenMuecke 谢谢先生。当我可以解决这个问题时,我会用我更新的代码告诉你。我这样做只是为了学习。

标签: c# linq asp.net-mvc-5


【解决方案1】:

我想在这里发布完整的工作代码。

@helper ShowTree(List<Scaffolding.Controllers.MenuItem> menusList)
{
    <ul>
        @foreach (var item in menusList)
        {
            <li>
                <span>@item.Name</span>
                @if (item.Children!=null && item.Children.Any())
                {
                    @ShowTree(item.Children)
                }
            </li>
        }
    </ul>
}

@{
    var menuList = ViewBag.menusList as List<Scaffolding.Controllers.MenuItem>;
    @ShowTree(menuList);
}

public ActionResult Index()
{

    List<MenuItem> allMenu = new List<MenuItem>
    {
        new MenuItem {Id=1,Name="Parent 1", ParentId=0},
        new MenuItem {Id=2,Name="child 1", ParentId=1},
        new MenuItem {Id=3,Name="child 2", ParentId=1},
        new MenuItem {Id=4,Name="child 3", ParentId=1},
        new MenuItem {Id=5,Name="Parent 2", ParentId=0},
        new MenuItem {Id=6,Name="child 4", ParentId=4}
    };


    List<MenuItem> mi = allMenu
    .Where(e => e.ParentId == 0) /* grab only the root parent nodes */
    .Select(e => new MenuItem
    {
        Id = e.Id,
        Name = e.Name,
        ParentId = e.ParentId,
        Children = allMenu.Where(x => x.ParentId == e.Id).ToList()
    }).ToList();

    ViewBag.menusList = mi;

    return View();
}

public class MenuItem 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public virtual List<MenuItem> Children { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2017-11-21
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    相关资源
    最近更新 更多