ASP.Net MVC:如何利用递归技术展示多层父子嵌套关系
嘿,这个递归展示层级关系的需求我熟得很!我来给你一步步拆解实现方法,保证在Razor里完美展示N层嵌套的<ul>/<li>结构。
第一步:定义数据模型
首先我们需要一个对应数据库表的模型类,还要加一个Children集合来存储子节点,方便构建树形结构:
public class Category { public int ID { get; set; } public string Name { get; set; } public int ParentID { get; set; } // 用于存储当前节点的所有子节点 public List<Category> Children { get; set; } = new List<Category>(); }
第二步:在控制器中构建树形结构
为了避免递归过程中反复查询数据库(性能太差),我们先一次性把所有数据从数据库拉出来,然后在内存中构建完整的树形结构:
public IActionResult Index() // ASP.NET Core用IActionResult,老版MVC用ActionResult { // 这里模拟从数据库获取数据,实际项目替换成EF/Dapper等查询逻辑 var allCategories = _dbContext.Categories.ToList(); // 假设_dbContext是你的数据库上下文 // 筛选出所有根节点(ParentID=0的节点) var rootNodes = allCategories.Where(c => c.ParentID == 0).ToList(); // 递归给每个根节点添加子节点 foreach (var root in rootNodes) { PopulateChildren(root, allCategories); } return View(rootNodes); } // 递归填充子节点的私有方法 private void PopulateChildren(Category parent, List<Category> allItems) { // 找到当前父节点的所有直接子节点 var children = allItems.Where(c => c.ParentID == parent.ID).ToList(); foreach (var child in children) { // 先递归填充子节点的子节点,再添加到父节点的Children集合中 PopulateChildren(child, allItems); parent.Children.Add(child); } }
第三步:Razor视图的递归渲染
这里我们用局部视图来实现递归,这样代码更清晰易维护。
主视图(Index.cshtml)
主视图负责渲染根节点列表:
@model List<Category> <!-- 根节点的ul容器 --> <ul class="category-tree"> @foreach (var root in Model) { <!-- 调用局部视图渲染每个根节点及其子节点 --> <partial name="_CategoryNode" model="root" /> <!-- ASP.NET Core写法 --> <!-- 如果是老版MVC,用:@Html.Partial("_CategoryNode", root) --> } </ul>
递归局部视图(_CategoryNode.cshtml)
这是核心的递归部分,负责渲染单个节点以及它的所有子节点:
@model Category <li> <!-- 显示当前节点的名称 --> <span>@Model.Name</span> <!-- 如果当前节点有子节点,递归渲染子节点的ul列表 --> @if (Model.Children.Any()) { <ul> @foreach (var child in Model.Children) { <partial name="_CategoryNode" model="child" /> <!-- 递归调用局部视图 --> } </ul> } </li>
额外提示
- 性能优化:一定要先把所有数据加载到内存再构建树形,不要在递归视图里每次查询数据库,不然数据量大的时候性能会崩。
- 避免循环引用:要确保数据库里的ParentID不会出现循环(比如A的父是B,B的父是A),不然递归会导致栈溢出。
- 样式定制:可以给ul/li加CSS类,比如实现折叠展开效果,这部分就靠你自己的CSS功底啦~
内容的提问来源于stack exchange,提问作者Mist
相关产品推荐
相关产品推荐

