使用 Blazor 渲染未知深度的树结构
Render tree structure of unknown depth using Blazor
我正在使用以下递归函数来尝试渲染 html 手风琴。
它使用反射来收集给定对象的所有 属性 名称和值。对象是未知的数据树结构depth/children等
@* Accordoin HTML Template *@
<div class="accordion">
<input type="checkbox" id="accordion-1" name="accordion-checkbox" hidden>
<label class="accordion-header" for="accordion-1">
<i class="icon icon-arrow-right mr-1"></i>
Title
</label>
<div class="accordion-body">
<!-- Accordions content -->
</div>
</div>
@code {
public void BuildTree(object obj)
{
if (obj == null) return;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
{
//Build accordion body
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
//Build accordion header
IEnumerable enumerable = (IEnumerable)propValue;
if (enumerable != null)
foreach (object child in enumerable)
BuildTree(child);
}
else
{
//Build accordion header
BuildTree(propValue);
}
}
}
我的问题是如何以递归方式渲染 html?
我试过如下使用 RenderFragment :
RenderFragment BuildTree(object obj)
{
if (obj == null) return @<p>test</p>;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
{
return @<p>Some test markup</p>
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
IEnumerable enumerable = (IEnumerable)propValue;
if (enumerable != null)
foreach (object child in enumerable)
BuildTree(child);
}
else
{
BuildTree(propValue);
}
}
return @<p>Done</p>;
}
它构建但在运行时给出错误:
未处理的异常呈现组件:无法绑定到目标方法,因为它的签名与委托类型的签名不兼容。
我知道在 blazor 中必须有一种惯用的方法来执行此操作,但我无法理解递归如何与渲染片段一起工作。
我的2毛钱:组件可以自嵌套。对于我的大脑,这是呈现嵌套组件的最简单方法——一种非常物理的递归。我在工作,所以我无法为您完成一个可行的解决方案,但希望以下模板足够清晰。如果要显示所有分支,则完全放弃布尔逻辑或将 ShowChildren 初始化为 true 而不是 false;
Nestable.Razor
@if(ChildCollection is not null){
<div @onclick=ToggleVisibility >
<u>@DisplayForThisObject</u>
</div>
@if(ShowChildren){
foreach (var Child in ChildCollection){
<Nestable PassedObject=Child />
}
}
}
else {
@DisplayForThisObject;
}
@code {
[Parameter]
public object PassedObject {get; set;}
IEnumerable<object> ChildCollection {get; set;}
string DisplayForThisObject {get; set;}
bool ShowChildren {get; set;} = false;
protected override void OnInitialized()
{
DisplayForThisObject = SomePropertyToString();
ChildCollection = SomemethodToGetTheChildObjects(PassedObject);
base.OnInitialized();
}
void ToggleVisibility(){
ShowChildren = !ShowChildren;
}
}
我正在使用以下递归函数来尝试渲染 html 手风琴。 它使用反射来收集给定对象的所有 属性 名称和值。对象是未知的数据树结构depth/children等
@* Accordoin HTML Template *@
<div class="accordion">
<input type="checkbox" id="accordion-1" name="accordion-checkbox" hidden>
<label class="accordion-header" for="accordion-1">
<i class="icon icon-arrow-right mr-1"></i>
Title
</label>
<div class="accordion-body">
<!-- Accordions content -->
</div>
</div>
@code {
public void BuildTree(object obj)
{
if (obj == null) return;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
{
//Build accordion body
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
//Build accordion header
IEnumerable enumerable = (IEnumerable)propValue;
if (enumerable != null)
foreach (object child in enumerable)
BuildTree(child);
}
else
{
//Build accordion header
BuildTree(propValue);
}
}
}
我的问题是如何以递归方式渲染 html?
我试过如下使用 RenderFragment :
RenderFragment BuildTree(object obj)
{
if (obj == null) return @<p>test</p>;
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
{
return @<p>Some test markup</p>
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
IEnumerable enumerable = (IEnumerable)propValue;
if (enumerable != null)
foreach (object child in enumerable)
BuildTree(child);
}
else
{
BuildTree(propValue);
}
}
return @<p>Done</p>;
}
它构建但在运行时给出错误:
未处理的异常呈现组件:无法绑定到目标方法,因为它的签名与委托类型的签名不兼容。
我知道在 blazor 中必须有一种惯用的方法来执行此操作,但我无法理解递归如何与渲染片段一起工作。
我的2毛钱:组件可以自嵌套。对于我的大脑,这是呈现嵌套组件的最简单方法——一种非常物理的递归。我在工作,所以我无法为您完成一个可行的解决方案,但希望以下模板足够清晰。如果要显示所有分支,则完全放弃布尔逻辑或将 ShowChildren 初始化为 true 而不是 false;
Nestable.Razor
@if(ChildCollection is not null){
<div @onclick=ToggleVisibility >
<u>@DisplayForThisObject</u>
</div>
@if(ShowChildren){
foreach (var Child in ChildCollection){
<Nestable PassedObject=Child />
}
}
}
else {
@DisplayForThisObject;
}
@code {
[Parameter]
public object PassedObject {get; set;}
IEnumerable<object> ChildCollection {get; set;}
string DisplayForThisObject {get; set;}
bool ShowChildren {get; set;} = false;
protected override void OnInitialized()
{
DisplayForThisObject = SomePropertyToString();
ChildCollection = SomemethodToGetTheChildObjects(PassedObject);
base.OnInitialized();
}
void ToggleVisibility(){
ShowChildren = !ShowChildren;
}
}