-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use BuildRenderTree() as a RenderFragment? #10499
Comments
Calling |
Just to be sure, when you say calling I'm asking because it seems like using |
I meant in general, accessing But I will let other @dotnet/razor-compiler folks chime in whether they think this is something we should support and hence somehow make this work. Note: in your example, the __builder.OpenComponent<global::BlazorApp1.Components.MyWrapper>(2);
__builder.AddAttribute(3, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
base.BuildRenderTree(__builder);
})); So you are referring to the wrong builder and it's failing at runtime. That should also demonstrate why relying on |
Is there a "correct" approach to rendering a component's base HTML, then? Or is it unsupported and the hack the only way to do it currently? |
As I already said, the RenderFragment approaches look good to me. I think they will behave as expected. Either one of those: @code {
private RenderFragment WrapInRenderFragment() => builder => base.BuildRenderTree(builder);
} @((RenderTreeBuilder builder) => base.BuildRenderTree(builder)) |
Sorry, your previous comment made me think you meant using It's still the correct way to render a base component normally , right? An example of what I mean: // Foo.razor
@inherits Bar
@{
base.BuildRenderTree(__builder);
}
@code {
// Override some of Bar's methods/defaults here.
} |
Although it works today, I wouldn't recommend it. Let me summarize:
|
Okay, gotcha. So this is the proper way of doing it, if we're not replacing the default HTML (well, ignoring the fact that we could just define a // Foo.razor
@inherits Bar
@((RenderTreeBuilder builder) => base.BuildRenderTree(builder))
@code {
// Override some of Bar's methods/defaults here.
} Thanks a lot, that clears things up nicely! Edit: For the record, it would probably be a good idea to update the Blazor docs to include this, since every search result seems to reference the other GitHub issue as the correct way of doing things (and it was closed, so we can't leave a comment there anymore). |
Adding @SteveSanderson @javiercn @mkArtakMSFT I think we need to get crisp on what is and isn't supported when it comes to Blazor component inheritance. As @UniMichael pointed out, we've pointed users to |
My 2c: We definitely should stop telling people to use Having said that, we shouldn't do it until we have an alternate suggestion that our users will be happy with. |
When extending an existing component, one can use the
base.BuildRenderTree(__builder)
to render the base component's HTML.However, using
base.BuildRenderTree(__builder)
inside a component as aRenderFragment ChildContent
will fail.Here is an example:
The above fails with the following error:
This can be fixed by replacing the
base.BuildRenderTree(__builder)
block with aRenderFragment
factory method:My understanding is that this happens because
RenderFragment
is a delegate that operates on aRenderTreeBuilder
, whereas running the codebase.BuildRenderTree(__builder)
is used to generate the contents of the component'sBuildRenderTree()
method, which are two different things.I'm unable to find much documentation on the subject of using the
BuildRenderTree()
method inside aRenderFragment
. Is the above the correct way to handle this or will it lead to unexpected complications down the line?Edit:
You can also replace the private method with a Razor expression that returns a lambda instead, which leads me to believe that
RenderFragments
are handled differently by the Razor code generator (I'm guessing they're invoked when found):The text was updated successfully, but these errors were encountered: