首页 > 解决方案 > 使用 Blazor 创建递归列表结构

问题描述

我正在尝试<ul>在 Blazor 中创建一个递归列表,我所做的方式看起来合乎逻辑,但我有一个奇怪的行为,这是我的代码:

代表的类元素ul li

public class Element
{
    public string Title { get; set; }
    public Element Parent { get; set; }
    public int Index { get; set; }
}

ULComponent.Razor:

@if (DataItems?.Count() > 0)
{
  <ul>
        @foreach (var element in DataItems)
        {
            var children = DataItems.Where(e => e.Parent == element).OrderBy(e => e.Index);
            <li>
                @element.Title

                @if (children.Count() > 0)
                {
                    <UlComponent DataItems="children" />
                }
            </li>
        }
  </ul>
}

ULComponent.Razor.cs,后面的代码:

public partial class ULComponent
{
    [Parameter]
    public IEnumerable<Element> DataItems { get; set; }
}

Razor 页面背后的代码:

protected override void OnInitialized()
{
    var root = new Element { Title = "Root", Index = 1 };
    var element1 = new Element { Title = "Element 1", Index = 1, Parent = root };
    var element2 = new Element { Title = "Element 2", Index = 2, Parent = root };
    var element3 = new Element { Title = "Element 3", Index = 3, Parent = root };
    var element11 = new Element { Title = "Element 1.1", Index = 1, Parent = element1 };
    var element12 = new Element { Title = "Element 1.2", Index = 2, Parent = element1 };
    var element121 = new Element { Title = "Element 1.2.1", Index = 1, Parent = element12 };
    var element21 = new Element { Title = "Element 2.1", Index = 1, Parent = element2 };
    var element22 = new Element { Title = "Element 2.2", Index = 2, Parent = element2 };
    var element31 = new Element { Title = "Element 3.1", Index = 1, Parent = element3 };
    Elements = new List<Element> {root, element1, element2, element3, element11,
           element12, element121, element21, element22, element31};
}

剃须刀页面:

@if (Elements != null)
{
    <div class="row">
        <ULComponent DataItems="Elements"/>
    </div>
    
}

结果代码起来了。

Root
    Element 1
    Element 2
    Element 3
Element 1
    Element 1.1
    Element 1.2
Element 2
    Element 2.1
    Element 2.2
Element 3
    Element 3.1
Element 1.1
Element 1.2
    Element 1.2.1
Element 1.2.1
Element 2.1
Element 2.2
Element 3.1

我试图得到这个:

Root
Element 1
    Element 1.1
    Element 1.2
        Element 1.2.1
Element 2
    Element 2.1
    Element 2.2
Element 3
    Element 3.1

标签: c#asp.net-coreblazor

解决方案


组件可以嵌套在它们自己内部。只要你有正确的自引用数据,那么解压它就很容易。这样做的好处是,如果您稍后决定要将“动物”归类为“事物”,您只需将其 ParentID 更改为 8,就完成了。

元素.cs

public class Element
{
    public int ID { get; set; }
    public int? ParentID { get; set; }
    public string Name { get; set; }
}

父剃刀

<CascadingValue Value="Items">
    <ul>
        <RecursiveUI ParentID="null" />
    </ul>
</CascadingValue>
 
@code {
    List<Element> Items;

    protected override void OnInitialized()
    {
        Items = new List<Element>
        {
            new Element { ID=1, Name="Animals", ParentID = null},
            new Element { ID=2, Name="Mammals", ParentID = 1},
            new Element { ID=3, Name="Birds", ParentID = 1},
            new Element { ID=4, Name="Bears", ParentID = 2},
            new Element { ID=5, Name="Beavers", ParentID = 2},
            new Element { ID=6, Name="Eagles", ParentID = 3},
            new Element { ID=7, Name="Parakeets", ParentID = 3},
            new Element { ID=8, Name="Things", ParentID = null},
            new Element { ID=9, Name="Yo-yos", ParentID = 8},
            new Element { ID=10, Name="Computers", ParentID = 8}
        };
    }
}

递归UI.razor

@foreach (var item in Items.Where(i => i.ParentID == ParentID))
{
    <li>@item.Name
        @if (Items.Where(c=>c.ParentID == item.ID).Any())
        {
           <ul>
               <RecursiveUI ParentID="item.ID"/>  @*THIS IS THE MAGIC.*@
           </ul>
        }
    </li>
}

@code {
    [Parameter]
    public int? ParentID { get; set; }

    [CascadingParameter]
    List<Element> Items { get; set; }
}

推荐阅读