How to use either ?. or ?? to conditionally render Blazor template?
Asked Answered
P

1

6

I want to simplify the following

@if (Template != null)
{
    @Template
}
else
{
    <span>No contents!</span>
}

with either ?? or ?.

Is it possible?

Attempt

My attempts below

  • @Template?.BeginInvoke()
  • @{Template==null? @Template : <span> No data to display! </span>}
  • @(Template??<span> No data to display! </span>)

produce red squiggly lines.

Edit

I think I need to submit the real scenario that I want to simplify.

@typeparam T

@if (Items == null)
{
    if (NullTemplate != null)
    {
        @NullTemplate
    }
    else
    {
        <span style="color: red">Null...</span>
    }
}
else if (Items.Count == 0)
{
    if (EmptyTemplate != null)
    {
        @EmptyTemplate
    }
    else
    {
        <span style="color: red">Empty ...</span>
    }
}
else
{
    @HeaderTemplate

    foreach (T item in Items)
    {

        @ItemTemplate(item)
    }
}

    
@code{
    [Parameter] public RenderFragment NullTemplate { get; set; }
    [Parameter] public RenderFragment EmptyTemplate { get; set; }
    [Parameter] public RenderFragment HeaderTemplate { get; set; }
    [Parameter] public RenderFragment<T> ItemTemplate { get; set; }
    [Parameter] public List<T> Items { get; set; }
}

I don't want to buffer the incoming values to ****Template properties with private fields, pre-process the fields before rendering them (the fields) to HTML. In other words, no additional code in @code{} directive are allowed.

Packton answered 3/7, 2020 at 2:1 Comment(2)
I am not an expert in blazor, or razor syntax, however unless you do this completely in a code, this is about as good as it gets..Tims
@TheGeneral: I don't want to create a partial class derived from ComponentBase because generating HTML with BuildRenderTree is really cumbersome!Packton
P
2

It could work (I think) when you store the <span style="color: red">Null...</span> parts as RenderFragments. Would that be acceptable?

That would move this logic to the constructor or the SetParameters method.

[Parameter] public RenderFragment NullTemplate { get; set; } = builder => StubTemplate(builder, "Null");
[Parameter] public RenderFragment EmptyTemplate { get; set; } = builder => StubTemplate(builder, "Empty");

private static void StubTemplate(RenderTreeBuilder __builder, string what)
{
    <span style="color: red">@what</span>
}

Note that the __builder name is required.
And then you don't need any conditional code in the main component anymore:

@if (Items == null)
{
   @NullTemplate
}

Alternatively, you can omit the property initialization and do :

 @(EmptyTemplate ?? (builder => StubTemplate(builder, "Empty")))

but I would get dizzy of all the ().

Pilaf answered 5/7, 2020 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.