asp.net-coreblazor.net-8.0

How might I avoid repeat Blazor-generated HTML attributes between conditionally-rendered elements?


In a nutshell, how can I make this code better:

@if( this.OnClick_Async is not null ) {
    <div component-name="TermDisplay" class="basic"
            @onclick=@(async e => await this.OnClick_Async(e))
            onmouseover="if(@(this.Term.Context is not null) == true && @(this.Term.Context.Context is not null) == true) { window.DisplayMousePopup(event, `@this.Term.Context.Context.Term`); }">
        @this.Term.ToString()
    </div>
} else {
    <div component-name="TermDisplay" class="basic"
            onmouseover="if(@(this.Term.Context is not null) == true && @(this.Term.Context.Context is not null) == true) { window.DisplayMousePopup(event, `@this.Term.Context.Context.Term`); }">
        @this.Term.ToString()
    </div>
}

Because the attributes use Blazor, I'm not sure if I can simply cop out with attribute splatting.

Edit: I realize I may be asking the wrong question for the given code, but the main question remains.


Solution

  • On the assumption that OnClick_Async is probably a parameter Func or EventCallback, here's how you can change your specific case.

    I simplified the onmouseover to provide a Minimal Reproducible Example. You'll need to add your code back in.

    <div component-name="TermDisplay" class="basic"
         @onclick="this.OnButtonClick"
         onmouseover="window.DisplayMousePopup(event, `@_value`);">
        @_value
    </div>
    
    @code {
        [Parameter] public Func<MouseEventArgs, Task>? OnClick_Async { get; set; }
        [Parameter] public EventCallback<MouseEventArgs> OnClick { get; set; }
    
        private string _value = "Hello Blazor";
    
        private async Task OnButtonClick(MouseEventArgs e)
        {
            // if using a Event
            await this.OnClick.InvokeAsync(e);
    
            // If using a Func
            if (this.OnClick_Async is not null)
                await this.OnClick_Async.Invoke(e);
    
            // or if there's nothing to await
            this.OnClick_Async?.Invoke(e);
        }
    }
    

    The alternative in more complex situations is to build a RenderFragment using the RenderTreeBuilder. Here's the MS Docs article on the subject:

    https://learn.microsoft.com/en-us/aspnet/core/blazor/advanced-scenarios?view=aspnetcore-8.0