Blazor FAQ - Templated components

How do I conditionally add Blazor components’ template?

The if statement is used to display a component or fragment conditionally. If the condition evaluates to true, the component will be loaded to the view.

Whenever the properties used in the if statement changes, the condition evaluates to either true or false and adds or removes the component to the page.

Refer to the following code sample.

<button class="btn" @onclick="ButtonClicked">Show</button>
 
@if (ShowComponent)
{
    <FetchData></FetchData>
}
 
@code{
    public bool ShowComponent { get; set; }
 
    public void ButtonClicked(MouseEventArgs e)
    {
        ShowComponent = true;
    }
}
Permalink
How do you define a render fragment using a Razor template in Blazor?

Render fragments can be defined using Razor template syntax. The templated components can be rendered either using a Razor template with an argument or directly.

@page "/razor"

@{
    RenderFragment template = @<p>The time is @DateTime.Now.</p>;
    RenderFragment<Employee> ItemTemplate = (item) => @<p>Employee name is @item.Name.</p>;
}

@template
@ItemTemplate(emp)

@code {
    Employee emp = new Employee { Name = "Test" };
    public class Employee
    {
        public string Name;
    }
}

Reference link:

https://docs.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-3.0#razor-templates

Permalink
How do you create a generic template component?

Templated components are often generically typed. To define a generic component, use the @typeparam directive to specify type parameters

Generic template component

@typeparam TItem

<table class="table">
    <thead>
<tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            <tr>@RowTemplate(item)</tr>
        }
    </tbody>
    <tfoot>
        <tr>@TableFooter</tr>
    </tfoot>
</table>

@code {
    [Parameter]
    public RenderFragment TableHeader { get; set; }

    [Parameter]
    public RenderFragment<TItem> RowTemplate { get; set; }

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

    [Parameter]
    public IReadOnlyList<TItem> Items { get; set; }
}

When using generically typed components, the type parameter is inferred if possible.

<GenericTemplate Items="@forecasts">
    <TableHeader>
        <th>Date</th>
        <th>Temp. (C)</th>
        <th>Temp. (F)</th>
        <th>Summary</th>
    </TableHeader>
    <RowTemplate Context="forecast">
        <td>@forecast.Date.ToShortDateString()</td>
        <td>@forecast.TemperatureC</td>
        <td>@forecast.TemperatureF</td>
        <td>@forecast.Summary</td>
    </RowTemplate>
</GenericTemplate>
@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
}

Otherwise, the type parameter must be explicitly specified using an attribute that matches the name of the type parameter. In the following example, TItem=" WeatherForecast "specifies the type.

<GenericTemplate Items="@forecasts" TItem="WeatherForecast">
    <TableHeader>
        <th>Date</th>
        <th>Temp. (C)</th>
        <th>Temp. (F)</th>
        <th>Summary</th>
    </TableHeader>
    <RowTemplate Context="forecast">
        <td>@forecast.Date.ToShortDateString()</td>
        <td>@forecast.TemperatureC</td>
        <td>@forecast.TemperatureF</td>
        <td>@forecast.Summary</td>
    </RowTemplate>
</GenericTemplate>

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
}

Reference: https://docs.microsoft.com/en-us/aspnet/core/blazor/templated-components?view=aspnetcore-3.1

Permalink
How do you create a template component in Blazor?

Blazor supports templated components. These are components that accept one or more UI templates as parameters and these parameters can be used for component rendering.

A templated component can be created by using one or more component parameters of type RenderFragment or RenderFragment<T>. The RenderFragment is a part of the UI that is rendered by the component. It may have parameters that are used during the rendering of the component or while the RenderFragment is invoked.

Table template component

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            <tr>@RowTemplate(item)</tr>
        }
    </tbody>
    <tfoot>
        <tr>@TableFooter</tr>
    </tfoot>
</table>

@code {
    [Parameter]
    public RenderFragment TableHeader { get; set; }

    [Parameter]
    public RenderFragment<WeatherForecast> RowTemplate { get; set; }
    [Parameter]
    public RenderFragment TableFooter { get; set; }

    [Parameter]
    public WeatherForecast[] Items { get; set; }
}

When using a templated component, the template parameters can be specified using child elements that match the names of the parameters (TableHeader and RowTemplate in the following example).

<TableTemplate Items="@forecasts">
    <TableHeader>
        <th>Date</th>
        <th>Temp. (C)</th>
        <th>Temp. (F)</th>
        <th>Summary</th>
    </TableHeader>
    <RowTemplate Context="forecast">
        <td>@forecast.Date.ToShortDateString()</td>
        <td>@forecast.TemperatureC</td>
        <td>@forecast.TemperatureF</td>
        <td>@forecast.Summary</td>
    </RowTemplate>
</TableTemplate>

@code {
    WeatherForecast[] forecasts;

    protected override void OnInit()
    {
        forecasts = WeatherForecasts();
    }

    public WeatherForecast[] WeatherForecasts()
    {
        string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        }).ToArray();
    }
}
Permalink
How to define context in a template component in Blazor?

A parameter can be accessed by the template component (of type RenderFragment<T>) using the context property. The context parameter is the implicit parameter; however, the parameter can be changed using the Context attribute on the templated component.

<TableTemplate Items="@forecasts">
    <TableHeader>
        <th>Date</th>
        <th>Temp. (C)</th>
        <th>Temp. (F)</th>
        <th>Summary</th>
    </TableHeader>
    <RowTemplate Context="forecast">
        <td>@forecast.Date.ToShortDateString()</td>
        <td>@forecast.TemperatureC</td>
        <td>@forecast.TemperatureF</td>
        <td>@forecast.Summary</td>
    </RowTemplate>
</TableTemplate>

Alternatively, this attribute can be specified on the component element. So, this attribute applies to all specified template parameters.

<TableTemplate Items="@forecasts" Context="forecast">
    <TableHeader>
        <th>Date</th>
        <th>Temp. (C)</th>
        <th>Temp. (F)</th>
        <th>Summary</th>
    </TableHeader>
    <RowTemplate>
        <td>@forecast.Date.ToShortDateString()</td>
        <td>@forecast.TemperatureC</td>
        <td>@forecast.TemperatureF</td>
        <td>@forecast.Summary</td>
    </RowTemplate>
</TableTemplate>

Reference link:

https://docs.microsoft.com/en-us/aspnet/core/blazor/templated-components?view=aspnetcore-3.1

Permalink