0
votes

I have this code :

@foreach (var item in list)
{
 <input type="checkbox" @onchange="@(e => HandleCheckChanged(e, item.Name))" checked="@item.IsChecked">
}

private async Task HandleCheckChanged(ChangeEventArgs e, string itemName)
{
   // do something ...
   StateHasChanged();
}

if I check a checkbox it calls the HandleCheckChanged and the checkbox is checked
But if I change the list items the previews checked checkbox is still checked and is not updated based on the new list items.

for example suppose that I have a list of ordered numbers {1-20} I follow these steps :
1 : list = GetAll().Where(c => c.Id < 10);
2 : I check the first checkbox (number 1)
3 : list = GetAll().Where(c => c.Id >= 10); (list updated and state has changed)
4 : the problem raises here , checkbox 11 is checked ??? but its value is false

2

2 Answers

2
votes

This happens because the renderer just sees the 'same' list of checkboxes and sees no reason to send an update.

A simple solution using @key to express that they are different items:

@foreach (var item in list)
{
 <input @key="item" type="checkbox" @onchange="@(e => HandleCheckChanged(e, item.Name))" checked="@item.IsChecked">
}

You do not have to call StatehasChanged() but it won't do any harm either.

0
votes

I had the same problem, what @Henk said is correct and there is also other solution:
You can wrap your HTML input with <EditForm Model='YourModel'>. because whenever EdtitForm.Model changes, EditForm.OnParametersSet is excuted and OnParametersSet will call StateHasChanged to rerender the existing component. Blazor-university has good explanation.