Blazor 中的递归标记

Posted

技术标签:

【中文标题】Blazor 中的递归标记【英文标题】:Recursive markup in Blazor 【发布时间】:2021-10-25 01:25:45 【问题描述】:

我有一个 LogModel,它具有 LogModel 类型的 Children 属性,因此是递归/嵌套结构。 还有一个 Collapsed bool 属性和一个 Description 字符串。

我试图在 Blazor 服务器端标记中显示此内容,但无法弄清楚如何处理递归片段。

我希望它显示描述,带有一个 +/- 按钮,该按钮具有切换 Collapse 属性的 @onclick,然后控制引导程序中的折叠类,从显示中折叠/隐藏所有子项。 比如这个例子:How to collapse/expand Razor components using Blazor syntax?

我的第二个想法是在代码中执行递归部分,它返回一个标记字符串。 这显示正常,但后来我无法弄清楚如何将 +/- 按钮绑定到一个事件以切换折叠的属性,因为 @onlick 不能从我读过的 MarkupString 内部完成。

提前致谢, 亚伦。

【问题讨论】:

一些示例代码将有助于显示您到目前为止的目标? 你有多少层或者你想暴露多少? 它不是无限的,但我希望代码能够通过真正的递归/嵌套解决方案无限地处理它。 【参考方案1】:

这是基于您提供的信息的解决方案。这并不漂亮:您需要对 Bootstrap CSS 进行排序以满足您的需求。

LogModel.cs

using System.Collections.Generic;

namespace ***.Answers

    public class LogModel
    
        public string Description  get; set; 

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

    

LogDisplayControl.razor

@namespace ***.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);
    

【讨论】:

递归初始化器会很酷。少得多的代码。要我编辑一个吗? @HenkHolterman 是的,请随意。这是我今天早上开始喝咖啡之前的第一枪。我已经知道哪里可以改进了! 你太棒了,非常感谢。我想知道您是否可以使用引用自身的控件。我现在就试试这个。我会尽快将其标记为已回答。

以上是关于Blazor 中的递归标记的主要内容,如果未能解决你的问题,请参考以下文章

数据--第21课-递归课后练习

Weblogic 和递归 JSP 标记

Maven 版本/scm 标签/Plexus DirectoryScanner 中的无限递归错误?

在递归标记中查找最高级别的组

汉诺塔的非递归实现(借助堆栈模拟递归)

如何使用LXML以递归方式查找XML标记?