-
Notifications
You must be signed in to change notification settings - Fork 10.3k
[Blazor] component inheritance, rendering logic in base component #21664
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
Comments
Thanks for contacting us. |
This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes. See our Issue Management Policies for more information. |
@mkArtakMSFT I'm using Razor RenderFragments in the overrides eg: public override void SetupColumns()
{
this[nameof(OrganizationQueryModel.Id)].RazorTemplate = (OrganizationQueryModel context) =>
@<div>
<img class="img-thumbnail circle thumb96 d-inline-block m-0" src="@(LinkGenerator.GetPathByAction<OrganizationController>(x=>x.Picture(context.Id)))" />
</div>;
} I'll make a follow-up issue |
Thanks for the key detail, @JvanderStad. |
I was thinking a little bit more about this; maybe the inherit mechanism can be even better: If by convention you would inherit from a base component which has a [Parameter]
public RenderFragment ChildContent { get; set; } 'Inject' the Razor content of the inherited component into the protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
__builder.OpenComponent<BaseComponent>(0);
__builder.AddAttribute(1, "ChildContent", (RenderFragment)( (builder2) => {
// Code generation for the inherited component
} ));
__builder.CloseComponent();
} alternatively Set the value of ChildContent = @"generated code from this component";
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
base.BuildRenderTree(__builder);
} This would shortcut the need to define parent/child content by simply inheriting from another component Possible related: #7268 |
We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources. |
base with a ChildContent and bool field
derived .razor
derived class method
it works .... |
Hi there, I have just been searchin for this kind of thing, what I would liike to do is class inheritance, For for eg. I have I component that I want to open as a dialog and I want other components to share this common dialog logic.
|
@LukeTOBrien Great minds think alike, @inherits Dialog |
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process. |
I would like to add one more on this context. When we define a component inheriting from another component, I would like razor code generator to add the Current implementation requires us to set the |
Something else to think about, I'd like a super-simple way to just be able to supply default implementation to existing controls. For example, given the following code (which is used repeatedly in my app: <HxInputNumber CssClass="w-50" TValue="int" @bind-Value="viewModel.NewRoleModel.DependentSourceMax">
<InputGroupStartTemplate>
<span class="input-group-text" @onclick="@(() => DecrementRole(c => c.DependentSourceMax))"><i class="fa-solid fa-minus"></i></span>
</InputGroupStartTemplate>
<InputGroupEndTemplate>
<span class="input-group-text" @onclick="@(() => IncrementRole(c => c.DependentSourceMax))"><i class="fa-solid fa-plus"></i></span>
</InputGroupEndTemplate>
</HxInputNumber>
@code
{
public void IncrementRole(Expression<Func<NewRoleModel, int>> outExpr)
{
var expr = (MemberExpression) outExpr.Body;
var prop = (PropertyInfo) expr.Member;
var value = (int)prop.GetValue(viewModel.NewRoleModel);
if (value >= 10) return;
value++;
prop.SetValue(viewModel.NewRoleModel, value);
}
public void DecrementRole(Expression<Func<NewRoleModel, int>> outExpr)
{
var expr = (MemberExpression) outExpr.Body;
var prop = (PropertyInfo) expr.Member;
var value = (int)prop.GetValue(viewModel.NewRoleModel);
if (value <= 0) return;
value--;
prop.SetValue(viewModel.NewRoleModel, value);
}
} ... I would like to basically inherit from HxInputNumber and specify the This way, I wouldn't have to re-implement all the bindings I want to use, or anything like that. HTH! |
Am I right in saying that this feature would allow me to write a set of razor in the inherited class, such as a wrapper, and then call the build render tree in that to then render the concrete classes razor where required? If so this is exactly what I need right now.. |
Thanks for contacting us. @inherits BaseComponent
@{
base.BuildRenderTree(__builder);
} |
@mkArtakMSFT I dont feel like this approach meets the standards set by a lot of the other parts of the framework, specifically people using the framework should be able to fall into the "pit of success". At the very least it seems like there could be a method on the base type which doesnt take the As for the breaking change, you could still call |
Indeed, having an interface like |
I would like to propose a very simple inheritance improvement with Blazor components:
Simply put: If you would inherit from a base .razor component and you haven't specified any content in the inherited .razor component, do not override the
BuildRenderTree
method.Why? I have created .razor components decorated with the abstract keyword in the partial class. The rendering logic (layout) is located in the base .razor component; this gives me the benefit of re-usage. If I inherit from this base component,
BuildRenderTree
is method is always overriden, even if I haven't specified any content. I can work around this, but its unnecessary redundant.How is it working now?
BaseComponent.razor
InheritNoContent.razor
InheritNoContentBaseRender.razor
If I use the above sample in a Razor file:
the output would be:
The above pattern is working, however it's quite redundant to create 2 razor components for every implementation of BaseComponent. I'm also calling
base.BuildRenderTree(__builder);
myself, this feels a bit hacky and possible unsupported/not recommended.My proposal:
If you would inherit from a base .razor component and you haven't specified any content, do not generate the override
BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
,or, as an alternative, call the base implementation.
Sample:
BaseComponent.razor
InheritNoContent.razor
If I use the above sample in a Razor file:
the output would be:
The text was updated successfully, but these errors were encountered: