Templated Component with RenderFragment in Blazor

Templated Component with RenderFragment in Blazor

What RenderFragment is and how to use it in an application will be covered in this blog. The component and content are rendered with the aid of the RenderFragment. Reusing the components is made easier by the templated component.

RenderFragment and RenderFragment<T> are the two different sorts of render elements.

RenderFragment - It is a just a simple razor content RenderFragment<T> - It allows parameters within the razor content. The context keyword helps to set a parameter within the razor content.

Let's start by looking at a simple RenderFragment example. The code for the child component is as follows. In this case, ChildContent is declared as RenderFragment. The UI segment is rendered by this RenderFragment. additionally, the @ChildContent is put within the <div> element.

Child.razor
<h3>Child</h3>
<div class="alert alert-primary">
    @ChildContent
</div>
@code 
{
    [Parameter]
    public RenderFragmentChildContent { get; set; }
}

A parent component comes next. Here, the string "Have a nice day!" has been inserted inside the child component. That is a child component parameter.

Parent.razor
@page "/Parent"
<Child>
    Have a nice day!
</Child>

The outcome of the preceding code is as follows. In this scenario, the parent component renders the child component along with a simple UI message (Have a nice day!).

RenderFragment in Blazor

Multiple Render Fragments

The following example will demonstrate how to pass multiple render fragments. FirstChildContent and SecondChildContent are two RenderFragements that are declared in the Child.razor code below. And inside the div element, the two Render Fragments are displayed.

Child.razor
<h3>Child</h3>

<div>First Child Content</div>
<div class="alert alert-primary">
    @FirstChildContent
</div>

<div>Second Child Content</div>
<div class="alert alert-secondary">
    @SecondChildContent
</div>

@code {
    [Parameter]
    public RenderFragmentFirstChildContent { getset; }
    [Parameter]
    public RenderFragmentSecondChildContent { getset; }
}

The following is a parent component. Here inside the <child> component <FirstChildContent> and <SecondChildContent> are added with is UI parameter.

Parent.razor
@page "/Parent"

<Child>
    <FirstChildContent>
       First Content: Have a nice day!
    </FirstChildContent>

    <SecondChildContent>
        Second Content: Wishing you a great day!
    </SecondChildContent>
</Child>

The code above produced the output below. You can see that the parent component is showing both child contents in this output.

RenderFragment in Blazor

Templated Component with Generically Type

Next, you're going to see how to pass generic values to template. Following is the TableTemplate  component. To render a generic <T> value, an IReadOnlyList<TItem> items property is added. It will display the table rows. RenderFragment? TableHeader will provide the value to render the table header name. RenderFragment<TItem>? RowTemplate will provide table row values.

TableTemplate.razor
@typeparam TItem
@using System.Diagnostics.CodeAnalysis

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            if (RowTemplate is not null)
            {
                <tr>@RowTemplate(item)</tr>
            }
        }
    </tbody>
</table>
@code {
    [Parameter]
    public RenderFragmentTableHeader { getset; }
    [Parameter]
    public RenderFragment<TItem>? RowTemplate { getset; }
    [ParameterAllowNull]
    public IReadOnlyList<TItemItems { getset; }
}

The code below is the Table.razor component. It will display two tables with the same TableTemplate. The code has two classes Movie and Production. The Movie has three property variables ID, Name and ReleaseYear. And the Production has two property variables ID and Name. Values are initialized for both Movie and Production. And passed to TableTemplate

Table.razor
@page "/table"

<h4>Movies</h4>

<TableTemplate Items="Movies" Context="movie">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
        <th>Release Year</th>
    </TableHeader>
    <RowTemplate>
        <td>@movie.ID</td>
        <td>@movie.Name</td>
        <td>@movie.ReleaseYear</td>
    </RowTemplate>
</TableTemplate>

<h4>Productions</h4>

<TableTemplate Items="Productions" Context="prod">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@prod.ID</td>
        <td>@prod.Name</td>
    </RowTemplate></TableTemplate>

@code {
    private List<MovieMovies = new()
    {
        new Movie { ID =1, Name = "Frozen", ReleaseYear = 2013 },
        new Movie { ID =2Name = "Moana"ReleaseYear = 2016  },
        new Movie { ID =3Name = "Dumbo"ReleaseYear = 2019  }
    };

    private class Movie
    {
        public int ID { getset; }
        public stringName { getset; }
        public int ReleaseYear { getset; }
    }

    private List<ProductionProductions = new()
    {
        new Production { ID =1Name = "Pixar Animation Studios" },
        new Production { ID =2Name = "Marc Platt Productions" },
        new Production { ID =3Name = "Bardel Entertainment" }
    };
    private class Production
    {
        public int ID { getset; }
        public stringName { getset; }
    }
}

The below image is an output of the above code. Here you can see both Movie and Production data are displayed with the same template.

RenderFragment in Blazor

Alternate ways to pass parameters

In the below example, the Context is added in  <RowTemplate>
<TableTemplate Items="Movies">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
        <th>Release Year</th>
    </TableHeader>
    <RowTemplate Context="movie">
        <td>@movie.ID</td>
        <td>@movie.Name</td>
        <td>@movie.ReleaseYear</td>
    </RowTemplate>
</TableTemplate>

RenderFragment<TValue> has a context parameter. So in the below example the Context is not set. Instead of that parameters are passed using RenderFragment<TValue>’s context  (@context.{PROPERTY}).

<TableTemplate Items="Movies">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
        <th>Release Year</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.ID</td>
        <td>@context.Name</td>
        <td>@context.ReleaseYear</td>
    </RowTemplate>
</TableTemplate>

In the final method the TItem is specified explicitly.

<TableTemplate Items="Movies" TItem="Movie">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
        <th>Release Year</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.ID</td>
        <td>@context.Name</td>
        <td>@context.ReleaseYear</td>
    </RowTemplate>
</TableTemplate>

I hope this helps you. Keep coding.

Comments

  1. Smooth and excellent explanation.
    Could you please do more on this topic,
    Thank you very much.

    ReplyDelete

Post a Comment

Popular posts from this blog

Entity Framework Core (EF) with SQL Server LocalDB

Creating a C# Azure Function with Visual Studio: Step-by-Step Guide

Exploring EventCallback in Blazor: Building Interactive Components