问题描述
我正尝试在Blazor中创建一个递归列表<ul>
,这样做看起来合乎逻辑,但我得到了一个奇怪的行为,这是我的代码:
表示ul li
的Class元素:
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
推荐答案
组件可以嵌套在自身内部。只要您有适当的自引用数据,那么将其解包就非常容易。这样做的好处是,如果您后来决定要将动物&物品归类为&q;物品,则只需将其ParentID更改为8,即可完成。
Element.cs
public class Element
{
public int ID { get; set; }
public int? ParentID { get; set; }
public string Name { get; set; }
}
Parent.razor
<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}
};
}
}
RecursiveUI.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; }
}