在ASP.NET Core中使用剃刀在表中进行递归 [英] Recursion in a table using razor in ASP.NET Core
问题描述
我有此产品类别模型:
public class ProductCategory
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
}
我想使用父级ID在列表列表中显示类别和子类别的列表(最多三个级别),如下所示:
Using the parent Id, I want to display a list of categories and sub-categories (max three levels) in a tabeled list, like so:
<table>
<tr><td colspan="3">Category #1</td></tr>
<tr><td></td><td>Category #1.1</td><td></td></tr>
<tr><td></td><td>Category #1.2</td><td></td></tr>
<tr><td colspan="2"></td><td>Category #1.2.1</td></tr>
<tr><td colspan="2"></td><td>Category #1.2.2</td></tr>
<tr><td colspan="3">Category #2</td></tr>
</table>
我尝试实施此解决方案,但我不这样做无法理解我应该如何将数据传递到局部视图.而且我的类别没有提及孩子,而是提及了父母.
I tried to implement this solution, but I don't understand how I'm supposed to pass the data to the partial view. And my categories don't have a reference to children, but rather to parents.
推荐答案
要模仿您引用的解决方案,您必须至少向您的实体添加一个导航属性.这样,您可以有效地枚举每个ProductCategory
的子代.
To mimic the solution you refer to, you'd have to add at least one Navigation Property to your entity. This way you can effectively enumerate the children of each ProductCategory
.
我建议使用以下实体声明,这不会对数据库造成任何额外的副作用.为了方便起见,它具有两个导航属性:
I would suggest the following entity declaration, which would cause no extra side effects in the database. It has two Navigation properties for convenience:
public class ProductCategory
{
public int Id { get; set; }
public string Title { get; set; }
[ForeignKey(nameof(ParentCategory))]
public int? ParentId { get; set; }
public ProductCategory ParentCategory { get; set; } //nav.prop to parent
public ICollection<ProductCategory> Children { get; set; } //nav. prop to children
}
现在,如果您有一个包含ParentCategory记录的填充良好的数据库集,则可以按以下操作方法查询它:
Now, if you have a nicely filled database set with ParentCategory records, you could query it in an action method as follows:
public IActionResult Index()
{
//get all categories, so we have each and every child in Context
var categories = yourDbContext.ProductCategories.Include(e => e.Children).ToList();
//only need top level categories in the View
var topLevelCategories = categories.Where(e => e.ParentId == null);
return View(topLevelCategories);
}
然后,该视图将这些顶级类别作为模型(我强烈建议为此创建一个ViewModel),并使用Partial递归呈现所有子级:
This view would then take these top level categories as a model (I would strongly recommend creating a ViewModel for this), and use a Partial to render all children recursively:
@model IEnumerable<ProductCategory>
<table>
@Html.Partial("CategoryRowPartial", Model)
</table>
最后,也接收到IEnumerable<ProductCategory>
的CategoryRowPartial
看起来像这样.它以递归方式调用自己以显示所有子项:
Finally, the CategoryRowPartial
, which also receives an IEnumerable<ProductCategory>
would look like this. It calls itself recursively to display all children:
@model IEnumerable<ProductCategory>
@foreach (var category in Model)
{
<tr><td>@category.Title</td></tr>
@Html.Partial("CategoryRowPartial", category.Children)
}
现在,这既没有考虑每个孩子的水平,也没有考虑到空的(甚至是草率的)td的&科尔斯潘.就个人而言,我将为此使用<ul>
或<ol>
.它们应用于显示层次结构.
Now, this doesn't take into account the level of each child nor the empty (and rather sloppy) td's & colspans. Personally, I'd use <ul>
or <ol>
for this. They are meant to be used to display hierarchies.
如果您坚持使用<table>
,我再次建议创建一个专门的视图模型,该模型可以容纳每个表行的深度".
If you insist on using a <table>
, I again recommend to create a specialized View Model which could hold the "depth" of each table row.
这篇关于在ASP.NET Core中使用剃刀在表中进行递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!