在ASP.NET Core中使用剃刀在表中进行递归 [英] Recursion in a table using razor in ASP.NET Core

查看:202
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆