Home > database >  Call Blazor Template function in a loop, wrapped in another HTML element?
Call Blazor Template function in a loop, wrapped in another HTML element?

Time:06-17

I'm working on a Blazor component with a table where it makes sense to factor out a couple pieces of the template. However it's not rendering correctly and the td elements I'm producing are not ending up inside the tr element, but instead are at the same level.

Below is a simplified version of the code. The body has the problem while the footer renders correctly. What is the correct way to accomplish what I'm trying to here? I know I could avoid all of the Razor syntax and just create a function that returns a raw MarkupString, but that doesn't seem like it should be necessary for a case like this.

<table>
<tbody>
    @foreach (var row in data)
    {
        @:<tr>
        RenderRow(row);
        @:</tr>
    }
</tbody>
<tfoot>
    <tr>
        @if (footerRow != null)
        {
            RenderRow(footerRow);
        }
    </tr>
</tfoot>
</table>

@{
    void RenderRow(Row row)
    {
        <td>@row.RowNum</td>
        RenderRowHalf(row.Left);
        RenderRowHalf(row.Right);
    }

    void RenderRowHalf(RowHalf half)
    {
        <td>@half.Foo</td>
        <td>@(Util.ColorNumber(half.Bar))</td>
    }
}

CodePudding user response:

A lot to unpick here - using @: before the <tr>, then calling a C# method is switching context and Blazor will auto-close the tag - get rid of the @: - not needed.

Change your methods to return RenderFragment<T> - the Blazor way of creating a fragment of Razor markup. Call them with @ prefix to switch back to C#.

The <text> tag helper just provides a way to group markup in the C# code sectiion.

Use @code for your C# code, otherwise it is scoped to each render cycle.

<table>
<tbody>
    @foreach (var row in data)
    {
        <tr>
        @RenderRow(row)
        </tr>
    }
</tbody>
<tfoot>
    <tr>
        @if (footerRow != null)
        {
            @RenderRow(footerRow)
        }
    </tr>
</tfoot>
</table>

@code
{
    RenderFragment<Row> RenderRow => row =>
    @<text>
        <td>@row.RowNum</td>
        @RenderRowHalf(row.Left)
        @RenderRowHalf(row.Right)
    </text>
    ;

    RenderFragment<RowHalf> RenderRowHalf => half =>
    @<text>
        <td>@half.Foo</td>
        <td>@(Util.ColorNumber(half.Bar))</td>
    </text>
    ;
}
  • Related