问题
I'm wondering if it's possible to reference child elements in the ChildContent
parameter of a component. I can pass values from parent components to children explicitly or by using a cascading parameter, but there is no great way for a parent component to "know" about elements inside the ChildContent
RenderFragment
. A possible use-case for this would be a UIList
component that gets the number of UIListItems
that have been added to the UIList
component during the render process.
I've attempted to override the BuildRenderTree
method on my component to manually manipulate ChildContent
RenderFragment
but my only options are to render or ignore the fragment (I can't peek the content of the RenderFragment
delegate).
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
int seq = 0;
base.BuildRenderTree(builder);
builder.OpenElement(seq++, "div");
builder.AddContent(seq++, this.ChildContent);
builder.CloseElement();
}
I'm wondering if something like below is possible. Please note that the syntax below is not valid, only an example to get the point across.
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();
}
回答1:
This is certainly not possible, at least not in the foreseeable future. The RenderFragment represents a chunk of content to render, the content of which, as far as I know, and for the time being, cannot be access programmatically, the way you want...
In Blazor, and in life as well, the flow of data is from a parent to a child component. I guess this is why one must design his software in accordance with this "inherent" limitation. In principal I believe anything is achievable, depending on, Dan Roth would say, resources available.
What's about Templated Components ? With Templated Component, your UIList component knows and determine the number of UIListItems to render...
Incidentally, I guess this is the only added value I can provide in this answer: You are not using the sequence properly. Steve Anderson has written an article about this; search for it).You shouldn't use an incrementing variable to issue the sequence. You should use numbers instead, starting with 0.
Hope this helps...
回答2:
As Issac states they way you are attempting to solve your problem is not possible with Blazor. However, it is possible for child elments to register themselves with a parent using a CascadingParameter. This seems like it would achieve what you want it's just coming at it from the other direction. Let me try an example...
Given this setup
<ParentComponent>
<ChildComponent></ChildComponent>
<ChildComponent></ChildComponent>
<ChildComponent></ChildComponent>
</ParentComponent>
I think you looking for an output like this
<div>
<p>Total Items: 3</p>
<div>Child Component</div>
<div>Child Component</div>
<div>Child Component</div>
</div>
Parent Component
<div>
<p>Total Items: @ItemCount</p>
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
</div>
@functions {
private int ItemCount;
public void AddItem()
{
ItemCount++;
StateHasChanged();
}
}
<div>Child Component</div>
@functions {
[CascadingParameter] private ParentComponet Parent { get; set; }
protected override void OnInit()
{
Parent.AddItem();
}
}
This should achieve what you're looking for if I understood your need correctly.
One thing I would say is try and stay away from overriding BuildRenderTree
, I've written a blog post about how to do it correctly but also point out why you probably shouldn't.
来源:https://stackoverflow.com/questions/56453173/is-it-possible-to-get-a-list-of-renderfragments-when-overriding-buildrendertree