2
votes

An Angular component can have an arbitrary number of child templates that it references. For instance, I could make a Foo component that specifies some body content inline, along with templates for additional content:

<Foo>
    This is my body
    <ng-template #header>
        This is my header
    <ng-template>
    <ng-template #footer>
        This is my footer
    <ng-template>
<Foo>

The Foo component can reference these templates as "ChildContent" and use them in its markup:

<div>
    <h1>
         <ng-template [ngTemplateOutlet]="header"></ng-template>
    </h1>
    <div>
       <p>Hi! I'm a Foo. My body content:</p>
       <p><ng-content></ng-content></p>
    </div>
    <h3>
         <ng-template [ngTemplateOutlet]="footer"></ng-template>
    </h3>
</div>

So my example usage of Foo (first code sample above) would be rendered into the DOM as:

    <div>
        <h1>
             This is my header
        </h1>
        <div>
           <p>Hi! I'm a Foo. My body content:</p>
           <p>This is my body</p>
        </div>
        <h3>
             This is my footer
        </h3>
    </div>

What is an equivalent in Blazor? In other words, I'd like to be able to define a component Foo such that it can be passed render fragments inline via in its child content markup.

1

1 Answers

4
votes

Blazor uses a RenderFragment class and property to produce template regions.

In the example below, we have templates for the Header, Body, and Footer as you described in your Angular example.

<div>
        <h1>
             @HeaderTemplate
        </h1>
        <div>
             <p>Hi! I'm a Foo. My body content:</p>
             <p>@ChildContent</p>
        </div>
        <h3>
             @FooterTemplate
        </h3>
    </div>

@code {

    [Parameter]
    public RenderFragment HeaderTemplate { get; set; } 

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

    [Parameter]
    public RenderFragment FooterTemplate { get; set; } 

}

Usage:

    <Foo>
        <HeaderTemplate>
             This is my header
        </HeaderTemplate>
        <ChildContent>
           <p>This is my body</p>
        </ChildContent>
        <FooterTemplate>
             This is my footer
        </FooterTemplate>
    </Foo>

Note: The order of the templates in the usage example do not matter.

Invalid Usage:

    <Foo>
        <!-- this will fail, because Blazor cannot determine where the <p> content belongs. -->
        <p>This is my body</p>
        <HeaderTemplate>
             This is my header
        </HeaderTemplate>
        <FooterTemplate>
             This is my footer
        </FooterTemplate>
    </Foo>