Home > Enterprise >  How to render a component passed as an attribute
How to render a component passed as an attribute

Time:09-27

Assume Row is a component like so:

<div class="row">
    <div class="col-6">
        @Column1
    </div>
    <div class="col-6">
        @Column2
    </div>
</div>

@code
{
    [Parameter]
    public ComponentBase Column1 { get; set; }

    [Parameter]
    public ComponentBase Column2 { get; set; }
}

Then assume that we use this like so:

<Row Column1="foo" Column2="foo"></Row>

@code {
    private readonly SomeComponent foo = new();
    private readonly SomeComponent bar = new();
}

I'd expect a row containing two columns containing the rendered components for foo and bar, but instead I get two columns containing "Example.Shared.Components.SomeComponent"

How then do you render sub-components passed into other components? Is there a better way to do this (i.e. something like ng-content in Angular?

As a side note, I'm looking for solutions that allow this programatically (as above), and using markup (as below):

<Row>
    <Column>
        <Foo></Foo>
    </Column>
    <Column>
        <Bar></Bar>
    </Column>
</Row>

CodePudding user response:

What you want is templated components

You still can't use SomeComponent foo = new();.

Instantiation is left to the renderer. But consider that a good thing, it lets you slip in an (item) context.

You'll also want to look at Cascading values, to expose the Row to the Columns.

And finally, there are plenty of commerical and Open versions of a Blazor DataGrid out there. Don't reinvent the whole wheel.

CodePudding user response:

Blazor is mostly declarative. So you should:

<Row>
    <Column1>
        <Foo></Foo>
    </Column1>
    <Column2>
        <Bar></Bar>
    </Column2>
</Row> 

You don't need to do new Foo() / new Bar()

Of course, you can take the very circuitous route of programmatically populating the RenderFragment. But it is generally not worth it. Instead, use Generic components and Polymorphism.

  • Related