Blazor 中的递归标记

Recursive markup in Blazor

我有一个 LogModel,它有一个 Children 属性 类型的 LogModel,所以一个 recursive/nested 结构。 还有一个 Collapsed bool 属性 和一个 Description 字符串。

我试图在 Blazor 服务器端标记中显示它,但无法弄清楚如何处理递归部分。

我希望它显示描述,带有一个 +/- 按钮,该按钮具有 @onclick 切换折叠 属性,然后控制 bootstrap 中的折叠 class, collapsing/hiding 所有 children 来自显示。
像这个例子:

我的第二个想法是在 Code 中做递归部分,returns 一个 MarkupString。 这显示正常,但后来我不知道如何将 +/- 按钮绑定到事件以切换折叠的 属性,因为 @onlick 不能从我读过的 MarkupString 内部完成。

提前致谢, 阿龙.

根据您提供的信息,这是一个解决方案。它并不漂亮:您需要对 Bootstrap CSS 进行排序以满足您的需要。

LogModel.cs

using System.Collections.Generic;

namespace Whosebug.Answers
{
    public class LogModel
    {
        public string Description { get; set; }

        public List<LogModel> Children { get; set; } = new List<LogModel>();

    }
}

LogDisplayControl.razor

@namespace Whosebug.Answers
<div class="container m-0 p-1 border border-secondary">
    <div class="row">
        <div class="col-11">
            @this.Model.Description
        </div>
        @if (this.hasChildren)
        {
            <div class="col-1">
                <button class="btn @this.buttonCss" type="button" @onclick="ToggleShow">
                    @buttonText
                </button>
            </div>
        }
    </div>
    @if (this.Show)
    {
        <div class="row">
            <div class="col-12">
                @if (this.hasChildren)
                {
                    @foreach (var child in this.Model.Children)
                    {
                        <LogDisplayControl Model="child"></LogDisplayControl>
                    }
                }
            </div>
        </div>
    }
</div>

@code {

    [Parameter] public LogModel Model { get; set; }

    private bool Show;

    private void ToggleShow()
        => this.Show = !this.Show;

    private bool hasChildren => this.Model?.Children?.Count > 0;

    private string buttonText => this.Show ? "Hide" : "Show";

    private string buttonCss => this.Show ? "btn-dark" : "btn-primary";

    private string HeaderCols => this.hasChildren ? "col-11" : "col-12";

}

演示页面

@page "/Accordion"
@foreach (var child in Model)
{
    <LogDisplayControl Model="child" />
}

@code {

    private List<LogModel> Model = new List<LogModel>();

    protected override void OnInitialized()
    {
        var model1_1_1 = new LogModel { Description = "Log Model 1.1.1" };
        var model1_1_2 = new LogModel { Description = "Log Model 1.1.2" };
        var model1_1 = new LogModel { Description = "Log Model 1.1", Children = new List<LogModel> { model1_1_1, model1_1_2 } };

        var model1_2 = new LogModel { Description = "Log Model 1.2" };

        var model1 = new LogModel { Description = "Log Model 1", Children = new List<LogModel> { model1_1, model1_2 } };

        var model2_1_1 = new LogModel { Description = "Log Model 2.1.1" };

        var model2_1 = new LogModel { Description = "Log Model 2.1", Children = new List<LogModel> { model2_1_1 } };

        var model2 = new LogModel { Description = "Log Model 2", Children = new List<LogModel> { model2_1 } };

        Model.Add(model1);
        Model.Add(model2);
    }
}