Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the recommended way of rendering a Blazor component dynamically?

I am new to Blazor with basic Angular and Vue.js experience. I would like to render a list of polymorphic components:

<ul>
    @foreach (fruit of fruits) 
         <li>HOW DO I RENDER FRUIT HERE??? </li> // render the fruit component
</ul>

@code {
   // Each member in the list is a subtype of Fruit
   var fruits = List<FruitComponent> {
       new PearComponent(),
       new AppleComponent()'
       new BananaComponent(),
       new RasberryComponent()
}

From what I've gleaned, there's a few ways to achieve this, each with their own disadvantages. An uncommon one suggests using an undocumented API call, which could become deprecated without notice, but it appears to be almost ideal. Another suggests emitting markup in the code which brings back the tedium of writing ASP.NET Server Controls. Finally, the most common suggests using conditional markup, while very simple, it couples the rendering code to the components it is rendering.

Most of the documentation I've read could be stale and no longer pertinent. With the official release of Blazor, what's the recommended way to achieve this?

like image 355
ATL_DEV Avatar asked Sep 30 '19 17:09

ATL_DEV


People also ask

How do I render a component in Blazor?

To force a component to rerender, use the “StateHasChanged” method in Blazor, to notify that the state has been changed and requires re-rendering.

How do you render a component on button click in Blazor?

In the method you check if it´s a single left click, single right click, double left etc. and fill your string variable accordingly (e. g. stringClicked = "leftsingle" ). Then you can show components by evaluating the value of a string variable.

What is RenderFragment in Blazor?

RenderFragment is used to render components or content at run time in Blazor. The RenderFragment class allows you to create the required content or component in a dynamic manner at runtime.


2 Answers

You have to create a RenderFragment, and use that as a renderer of your polymorphic component... I've used the default Blazor's template Counter component as a parent (CounterParent), and then the CounterChild inherits the CounterParent. I hope it helps!! Regards!

@page "/"

@foreach (CounterParent counter in components)
{
    RenderFragment renderFragment = (builder) => { builder.OpenComponent(0, counter.GetType()); builder.CloseComponent(); };
    <div>
        <div>Before the component</div>
        @renderFragment
        <div>Afterthe component</div>
    </div>
}

@code
{
    List<CounterParent> components = new List<CounterParent>() { new CounterParent(), new CounterChild() };
}
like image 58
Charles Deluxe Avatar answered Oct 18 '22 20:10

Charles Deluxe


You could use a switch statement that checks the types. You can place components in each of the cases, or render your li however you like.

<ul>
    @foreach (fruit in fruits)
    {
        switch(fruit)
        {
            case PearComponent p:
                <PearComponent ParameterOfSomeSort="p"></PearComponent>
                <li>Or render pears like this, if you want the li in it</li>
                break;
            case AppleComponent a:
                <AppleComponent></AppleComponent>
                break;
            case BananaComponent b:
                <BananaComponent></BananaComponent>
                break;
            case RaspberryComponent r:
                <RaspberryComponent></RaspberryComponent>
                break;
        }
    }
</ul>
like image 27
Tom Avatar answered Oct 18 '22 21:10

Tom