Create and Destroy dynamically Blazzor client side component?

Viewed 4310

I am trying to create and destroy dynamically a Blazor component which I have created on a for instance mouse click of a Button inside the page, anyway I am unable to find any information or examples on the topic.

  • How to create and destroy dynamically a Blazor component ?

Edit : I've added this sample block to clarify what I am trying.

This is inside "WindowContainer.razor"

@using System
@implements IDisposable

@using System.Net.Http
@inject HttpClient Http

<div draggable="false" id="UIWindowContainer" class="ui-window-content">
    <div draggable="true" >
        @Caption
        <!-- Minimize -->


    </div>

    @ChildContent
</div>


@code
{
    public void Dispose()
    {
    }
}

This is inside MainLayout.razor

div class="main">
    <div class="top-row px-4">
        <button @onclick="onClose">Exit</button>

        <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
    </div>

    <div class="content px-4">
        <WindowTest1.Components.WindowContainer @ref="sssss">test</WindowTest1.Components.WindowContainer>
    </div>
</div>
  • How to destroy WindowTest1.Components.WindowContainer ?
1 Answers

If you have only a few items, you should be able to use if/else flow to tell the render tree to show or remove the components. If you have a list of items, simply remove the item from the list and have the component re-render itself. Here is an example of a to-do list which dynamically adds/removes a div.

<input @bind-value="newItem"/><button @onclick="addItem" >Add Item</button>
@foreach(var item in ToDoList)
{
    <div>@item <button @onclick="(()=>removeItem(item))">Remove</button></div>
}



@code {
    string newItem = "";
    List<string> ToDoList = new List<string>() { "Get Eggs", "Get Milk", "Get Coffee", "Get More Coffee" };
    private void removeItem(string item)
    {
        ToDoList.Remove(item);
    }
    private void addItem()
    {
        ToDoList.Add(newItem);
        newItem = "";
    }

}

Of course you can replace the "div" with any blazor component and it will work exactly the same. The rendertree is built to efficiently handle scenarios like re-rendering after a list has been changed.

In the real-world, it might be more realistic to track changes using a property instead of simply adding and removing items from a list. In this way we can package up a list of our changes and send them to a server somewhere which will issue (add, update,delete) commands as needed. See my quick and dirty demo below:

Note that I've added a simple class SimpleString with a ToDo property appended. I've changed the foreach loop to check the property and build the To-Do and Completed sections accordingly.

<input @bind-value="newItem"/><button @onclick="addItem" >Add Item</button>

<h3>To-Do</h3>
@foreach(var item in ToDoList.Where(x=>x.ToDo))
{
    <div>@item.Value <button @onclick="(()=>removeItem(item))">Remove</button></div>
}

<h2>Completed</h2>
@foreach(var item in ToDoList.Where(x=>!x.ToDo))
{
    <p>@item.Value</p>
}


@code {
    class SimpleString
    {
        public string Value { get; set; }
        public bool ToDo { get; set; }
    }
    string newItem = "";
    bool showComponent = true;
    List<SimpleString> ToDoList = new List<SimpleString>() { new SimpleString { Value = "Get Eggs", ToDo = true }, new SimpleString { Value = "Get Milk", ToDo = true }, new SimpleString { Value = "Get Coffee", ToDo = true }, new SimpleString { Value = "Get More Coffee", ToDo = true } };
    private void removeItem(SimpleString item)
    {
        item.ToDo = false;
    }
    private void addItem()
    {
        ToDoList.Add(new SimpleString { Value = newItem, ToDo = true });
        newItem = "";
    }

}

It's also worth noting that Blazor components can implement the IDisposable interface in case you need to tap into the "disposal" of a component to free up unmanaged resources. In Blazor, an IDisposable component fires its dispose when the component is removed from the UI. In my example, it is not necessary to use IDisposable, but the dispose method would be called after the removeItem method completed via button click.

Related