Tree View MVC填充异常:三层存储过程返回正确但视图渲染错误
问题根因
你当前使用的是平级结构的ViewModel,循环调用存储过程时每次都会覆盖全局的CategoriesReport和namesReport属性,最终ViewModel中仅会保留最后一次循环得到的分类、报表数据,视图渲染时所有父级菜单都读取同一个全局子级集合,因此出现重复展示、仅显示首个数据的异常。
解决步骤
1. 重构嵌套结构的ViewModel
放弃原有的平级三个独立集合的结构,改为层级嵌套结构,代码如下:
// 孙级报表实体 public class ReportItem { public int ReportID { get; set; } public string ReportName { get; set; } // 可扩展其他需要的字段 } // 子级分类实体 public class CategoryItem { public int CategoryID { get; set; } public string Category { get; set; } // 嵌套存储当前分类下的报表列表 public List<ReportItem> Reports { get; set; } = new List<ReportItem>(); } // 父级分组实体 public class FamilyItem { public int FamilyID { get; set; } public string FamilyName { get; set; } // 嵌套存储当前分组下的分类列表 public List<CategoryItem> Categories { get; set; } = new List<CategoryItem>(); } // 最终的ViewModel public class ReportTreeViewModel { // 只需要一个根集合存储所有父级分组,子级数据都嵌套在内部 public List<FamilyItem> Families { get; set; } = new List<FamilyItem>(); }
2. 修正Controller数据填充逻辑
调整循环逻辑,将查询到的子级数据赋值到对应父级的嵌套集合中,不要覆盖全局属性:
var model = new ReportTreeViewModel(); // 先查询所有父级分组 model.Families = context.P_Mob_Get_ReportFamilies(user).ToList() .Select(f => new FamilyItem { FamilyID = f.FamilyID, FamilyName = f.FamilyName, // 填充当前分组下的所有分类 Categories = context.P_Mob_Get_ReportCategories(user, f.FamilyID).ToList() .Select(c => new CategoryItem { CategoryID = c.CategoryID, Category = c.Category, // 填充当前分类下的所有报表 Reports = context.P_Mob_Get_ReportNames(user, f.FamilyID, c.CategoryID).ToList() .Select(r => new ReportItem { ReportID = r.ReportID, ReportName = r.ReportName }).ToList() }).ToList() }).ToList(); // 测试输出逻辑和原有逻辑一致,数据已按层级存储 foreach (var family in model.Families) { Console.WriteLine(family.FamilyName); foreach (var cat in family.Categories) { Console.WriteLine(cat.Category); foreach (var report in cat.Reports) { Console.WriteLine(report.ReportName); } } } return View(model);
3. 修正视图嵌套循环逻辑
渲染时直接读取当前父级对应的嵌套子集合,不要读取全局集合,同时修正原视图中li标签错误添加href属性的问题:
<ul> @foreach (var family in Model.Families) { <li> <a href="#" class="menu_fam">@family.FamilyName</a> <ul class=""> @foreach (var cat in family.Categories) { <li> <a href="#" class="menu_cat">@cat.Category</a> <ul class=""> @foreach (var report in cat.Reports) { <li><a href="#" class="menu_name">@report.ReportName</a></li> } </ul> </li> } </ul> </li> } </ul>
内容的提问来源于stack exchange,提问作者Diogo Silva
相关产品推荐
相关产品推荐

