我如何在MVC核心创建一个多级菜单?



从我的helper函数呈现的HTML菜单是

  • 类别1
    • 类别2
  • 类别2
  • 三级
  • 4级

我将Category 2设置为Category 1的子类别。

不幸的是,当前的HTML帮助器随后再次显示Category 2为父节点。

Id  ParentCategoryId Description
1   NULL             Category 1
2   1                Category 2 
3   NULL             Category 3 
4   NULL             Category 4 
5   NULL             Category 5

如何修改辅助函数?

@{ Func<dynamic, IHtmlContent> ShowMenu(List<Category> cats) =>
@<ul>
@foreach (var cat in cats)
{
<li>
@cat.Description
@if (cat.Childs != null && cat.Childs.Any())
{
@ShowMenu(cat.Childs)(null)
}
</li>
}
</ul>; 
}

使用的类别模型为

public class Category
{
public int Id { get; set; }
public int? ParentCategoryId { get; set; }
public Category ParentCategory { get; set; }
[ForeignKey("ParentCategoryId")]
public List<Category> Childs { get; set; }
public string Description { get; set; }
}

html菜单在razor中通过

显示
@ShowMenu(Model.Categories)(null)

,

Model.Categories = context.Categories.ToList()

:由于给出了有用的答案,似乎我也应该将父类别作为参数传递。

@{ Func<dynamic, IHtmlContent> ShowMenu(List<Category> cats, Category parent) =>
@<ul>
@foreach (var cat in cats)
{
<li>
@cat.Description
@if (cat.Childs != null && cat.Childs.Any())
{
@ShowMenu(cat.Childs, cat)(null)
}
</li>
}
</ul>; }

cats显然包含了所有的类别。注意,您的函数将显示列表的所有元素,因此,如果外部列表包含所有元素,甚至包括内部元素,那么您遇到的问题就会发生。现在,一个简单的解决方案是更改您的函数,以便它也接收Category parent参数,并在外部调用时传递null,在递归调用时传递cat。现在,在<li></li>节点周围包装一个if,以检查ParentCategoryId是否与我们刚才讨论的parent参数值匹配。如果该条件的计算结果为true,则将显示li。如果不是,则不显示。

编辑我已经将我建议的if包装在逻辑中。由于我不熟悉这种语法,下面的代码可能不是应该这样写的,但我确信这段代码背后的思想是需要应用的。

@{ Func<dynamic, IHtmlContent> ShowMenu(List<Category> cats, Category parent) =>
@<ul>
@foreach (var cat in cats)
{
@if (((parent == null) && (cat.ParentCategoryId == null)) || (parent?.Id == cat.ParentCategoryId)))
{
<li>
@cat.Description
@if (cat.Childs != null && cat.Childs.Any())
{
@ShowMenu(cat.Childs, cat)(null)
}
</li>
}
}
</ul>; }

只像这样传递根类别:

Model.Categories = context.Categories.Where(c => c.ParentCategoryId == null).ToList()

最新更新