@" /> @" /> @"/>

Can I inherit a Blazor Component to add attributes?

103 Views Asked by At

Say I have a component MyComponent that prints out this HTML:

<my-component attr1="@(Attr1)"
              attr2="@(Attr2)"
              @attributes="@(AdditionalAttributes)">
    @(ChildContent)
</my-component>

Now I want to have MoreDetailedComponent that inherits MyComponent and declares Attr3. Can I reuse the above code somehow so I do not have to rewrite it (in reality there are tens of them):

@inherits MyComponent

<my-component attr1="@(Attr1)"
              attr2="@(Attr2)"
              attr3="@(Attr3)"
              @attributes="@(AdditionalAttributes)">
    @(ChildContent)
</my-component>
1

There are 1 best solutions below

0
Luke Vo On BEST ANSWER

Turn out it's very simple, I just extend the AdditionalAttributes like this:

// Non-extendable components
public class DefaultMdComponent : ComponentBase
{

    [Parameter(CaptureUnmatchedValues = true)]
    public IEnumerable<KeyValuePair<string, object>>? AdditionalAttributes { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }
    
}

// Extendable components should inherit this
public class DefaultInheritableComponent : DefaultMdComponent
{

    protected virtual IEnumerable<KeyValuePair<string, object>>? ProtectedAdditionalAttributes
        => null;
    
    protected IEnumerable<KeyValuePair<string, object>>? FinalAdditionalAttributes
    {
        get
        {
            if (AdditionalAttributes is null) { return ProtectedAdditionalAttributes; } 
            if (ProtectedAdditionalAttributes is null) { return AdditionalAttributes; }

            return AdditionalAttributes.Concat(ProtectedAdditionalAttributes);
        }
    }

}

MyComponent should prints it out like this:

<my-component attr1="@(Attr1)"
              attr2="@(Attr2)"
              @attributes="@(FinalAdditionalAttributes)">
    @(ChildContent)
</my-component>

MoreDetailedComponent does not need its own Razor file but instead just override ProtectedAdditionalAttributes:

public class MoreDetailedComponent : MyComponent
{

    // ...
    
    protected override IEnumerable<KeyValuePair<string, object>>? ProtectedAdditionalAttributes => 
        new KeyValuePair<string, object>[] 
        {
            new("attr3", Attr3)
        };
}