重写 BuildRenderTree 时是否可以获取 RenderFragments 列表?

Eri*_*and 5 c# blazor asp.net-core-3.0

我想知道是否可以在ChildContent组件的参数中引用子元素。我可以显式地或通过使用级联参数将值从父组件传递给子组件,但是父组件没有很好的方法来“了解” ChildContent RenderFragment. 一个可能的用例是一个组件,该组件获取在渲染过程中已添加到组件UIList的数量。UIListItemsUIList

我尝试重写BuildRenderTree组件上的方法以手动操作,ChildContent RenderFragment但我唯一的选择是渲染或忽略片段(我无法查看RenderFragment委托的内容)。

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        int seq = 0;
        base.BuildRenderTree(builder);
        builder.OpenElement(seq++, "div");
        builder.AddContent(seq++, this.ChildContent);
        builder.CloseElement();
    }
Run Code Online (Sandbox Code Playgroud)

我想知道下面这样的事情是否可能。请注意,下面的语法无效,只是一个说明要点的示例。

    protected int NumberOfItems{get;set;}

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        int seq = 0;
        base.BuildRenderTree(builder);
        builder.OpenElement(seq++, "div");
        foreach(var childFragment in this.ChildContent.GetFragments())
        {

           if(childFragment is UIListItem)
                NumberOfItems++;
           builder.AddContent(seq++,childFragment);
        }


        builder.CloseElement();
    }
Run Code Online (Sandbox Code Playgroud)

Chr*_*nty 10

正如 Issac 所说,您尝试解决问题的方式对于 Blazor 来说是不可能的。但是,子元素可以使用CascadingParameter向父元素注册自己。这看起来似乎可以实现你想要的,但它只是从另一个方向实现的。让我尝试举个例子...

鉴于此设置

<ParentComponent>
    <ChildComponent></ChildComponent>
    <ChildComponent></ChildComponent>
    <ChildComponent></ChildComponent>
</ParentComponent>
Run Code Online (Sandbox Code Playgroud)

我想你正在寻找这样的输出

<div>
    <p>Total Items: 3</p>
    <div>Child Component</div>
    <div>Child Component</div>
    <div>Child Component</div>
</div>
Run Code Online (Sandbox Code Playgroud)

父组件

<div>
    <p>Total Items: @ItemCount</p>
    <CascadingValue Value="this">
        @ChildContent
    </CascadingValue>
</div>

@code {
    private int ItemCount;

    public void AddItem()
    {
        ItemCount++;
        StateHasChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)
<div>Child Component</div>

@code {
    [CascadingParameter] private ParentComponent Parent { get; set; }

    protected override void OnInitialized()
        => Parent.AddItem();
}
Run Code Online (Sandbox Code Playgroud)

如果我正确理解了您的需求,这应该可以达到您想要的结果。

我想说的一件事是,尝试远离重写BuildRenderTree,我已经写了一篇关于如何正确执行此操作的博客文章,但也指出了为什么您可能不应该这样做。


Isa*_*aac 2

这肯定是不可能的,至少在可预见的将来是不可能的。RenderFragment 代表要渲染的一大块内容,据我所知,暂时无法以您想要的方式以编程方式访问其内容......

在 Blazor 中以及在生活中,数据流是从父组件到子组件。我想这就是为什么人们必须根据这种“固有的”限制来设计他的软件。原则上,我相信任何事情都是可以实现的,丹·罗斯会说,这取决于可用的资源。

模板化组件怎么样?使用模板化组件,您的 UIList 组件知道并确定要呈现的 UIListItems 的数量...

顺便说一句,我想这是我可以在这个答案中提供的唯一附加值:您没有正确使用该序列。史蒂夫·安德森(Steve Anderson)写了一篇关于此的文章;搜索它)。您不应使用递增变量来发出序列。您应该使用从 0 开始的数字。

希望这可以帮助...