Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add list of dynamic components in blazor

I just started to have a look in blazor (v0.3) and doing some test I wanted to add a list using blazor

First I created a List<string> to test a simple list in the same page

<ul>
    @foreach (var item in listItems)
    {
        <li>@item</li>
    }
</ul>


@functions {

    private List<string> listItems = new List<string>();
    private string newItem;

    private void AddItem()
    {
        if (string.IsNullOrEmpty(newItem))
            return;

        listItems.Add(newItem);
        newItem = "";
    }

}

this is working fine, is adding every element to the list when I add it. but then, i tried to add components, add a single component was easy, based on this question here but for a list I had the next problem:

  • I created a <li> compontent just to test the functionality of components, here is the component view
<li id="@ID">
    @Text
</li>   




@functions {
  [Parameter]
  string Text { get; set; } 
  [Parameter]
  string ID { get; set; }
}
  • then in the parent view
<input type="text" bind="TxtExample" name="inpAdd"/>
  <button onclick="@addCompoment">add comp1</button>
<div class="simple-list-list">
    @if (!componentListTest.Any())
    {
        <p>You have no items in your list</p>
    }
    else
    {
        <ul>
            @foreach (var item in componentListTest)
            {
                @item
            }
        </ul>
    }
</div>

@functions {

    private List<RenderFragment> componentListTest { get; set; }
    private int currentCount {get; set;}
    private string TxtExample { get; set; }

    protected override void OnInit()
    {
        currentCount = 0;
        componentListTest = new List<RenderFragment>();
    }


    protected void addCompoment()
    {

        componentListTest.Add(CreateDynamicComponent(currentCount));
        currentCount++;
    }


    RenderFragment CreateDynamicComponent(int counter) => builder =>
    {
        var seq = 0;
        builder.OpenComponent(seq, typeof(listExample));
        builder.AddAttribute(++seq, "Text", "text --  "+TxtExample);
        builder.AddAttribute(++seq, "id","listed-"+counter);

        builder.CloseComponent();

    };
}

when I load the fist element is loaded correctly: enter image description here

but when I entered the second one, all of them are replaced for the last one:

enter image description here

Any idea whats going on?

like image 672
TiGreX Avatar asked May 11 '18 19:05

TiGreX


People also ask

Do you need to render components ‘dynamically’ in Blazor?

But when you start building your web applications using Blazor you might get to a point where you decide you need to render your components ‘dynamically’. This usually means you need the application to render different things based on data (in other words the decision about which component (s) to render occurs at run-time and not compile-time).

Is there a Blazor component for complex parameters and data graphs?

It can get complicated when dealing with parameters and complex data graphs, and none of these solutions are any good, really. With .NET 6 Preview 1, the ASP.NET Core team introduced a built-in Blazor component, DynamicComponent, that allows you to render a component specified by type.

How do I pass a parameter to a Blazor component?

The namespace of the app is BlazorSample. Change the namespace to match your app's namespace. If dynamically-rendered components have component parameters, pass them into the DynamicComponent as an IDictionary<string, object>. The string is the name of the parameter, and the object is the parameter's value.

How can I create a dashboard panel in Blazor?

If you’re using a component library like Telerik UI for Blazor, it’s probably worth taking a moment to find a component which you can drop in to act as a dashboard panel. If you’re using the default Blazor project templates, you can use Bootstrap’s card classes to get to something that looks a little better in the browser:


1 Answers

You are making it too complicated. You don't need to dynamically instantiate components for this scenario to work.

You can just do a:

<ul>
    @foreach (var item in listItems)
    {
        <myComponent bind-myVar="@item"></myComponent>
    }
</ul>

And the components will be instantiated for you.

Also see here how to make the parameters work on your component.

like image 175
Flores Avatar answered Oct 13 '22 17:10

Flores