'Blazor List of components, shift values from components when removed from list
I'm trying to understand this issue I'm having in blazor 3.1 and appreciate anyone who could explain it to me.
- I have a list of items.
- I make child components by iterating through the list.
- Each component displays a private bool (IsSomething) value that can be toggled with a button.
- There's a close button (EventCallback) that removes the item from the list in the parent and I can't understand why the bool values of the remaining components shift.
[true] [false] [false]
remove 1st item (true in this example) in list gives
[true] [false]
I was expecting
[false] [false]
I would understand if all the bools would be false if the components are re-initialised or something but this behavior has me stumped.
Index.razor
@using ListComponentIssue.Shared
<h1>List Component Issue</h1>
@if (listOfItems != null)
{
<div style="display:flex; flex-direction:row;">
@foreach (var item in listOfItems)
{
<MyComponent ThisItem="@item" Close="close"></MyComponent>
}
</div>
}
Index.razor.cs
{
private List<Item> listOfItems = new List<Item>();
protected override void OnInitialized()
{
base.OnInitialized();
listOfItems.Add(
new Item()
{
Id = "1",
Title = "First"
}
);
listOfItems.Add(
new Item()
{
Id = "2",
Title = "Second"
}
);
listOfItems.Add(
new Item()
{
Id = "3",
Title = "Third"
}
);
listOfItems.Add(
new Item()
{
Id = "4",
Title = "Fourth"
}
);
listOfItems.Add(
new Item()
{
Id = "5",
Title = "Fifth"
}
);
}
public void close(Item itemToRemove)
{
listOfItems.Remove(itemToRemove);
}
}
MyComponent.razor
<div style="margin:5px;">
@ThisItem.Title is @isSomething
</div>
<div>
<button @onclick="toggleBool">Toggle bool</button>
<button @onclick="() => CloseToParent(ThisItem)">close</button>
</div>
</div>
@code {
private bool isSomething { get; set; }
[Parameter]
public Item ThisItem { get; set; }
[Parameter]
public EventCallback<Item> Close { get; set; }
private void toggleBool()
{
isSomething = !isSomething;
}
public async Task CloseToParent(Item itemToClose)
{
await Close.InvokeAsync(itemToClose);
}
public class Item
{
public string Id { get; set; }
public string Title { get; set; }
}
}
In another project, I use Radzen Dropdown multi select components and the selected items from components on the right shift/merge.
ex.:
[selected:1] [selected:2,3]
I remove the first component and the result is
[selected:1,2,3]
Removing components on the right does not change the components on the left.
My goal is for the user to be able to add and remove components dynamically.
Maybe my whole approach is wrong... any advice is appreciated
Solution 1:[1]
I wonder if this is the classic c# lambda capture problem. Try
@foreach (var item in listOfItems)
{
var temp = item;
<MyComponent ThisItem="@temp" Close="close"></MyComponent>
}
Solution 2:[2]
Use stored procedure:
CREATE PROCEDURE add_into_product (p_id INT, p_price INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
SET autocommit = OFF;
START TRANSACTION;
UPDATE product SET price = price + 10;
INSERT INTO product VALUES (p_id, p_price) ON DUPLICATE KEY UPDATE price = p_price;
COMMIT;
END
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=7291fa7ad68c7947445a7591429acb6d
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | pm100 |
| Solution 2 | Akina |
