Blazor 组件列表,从列表中删除时从组件转移值

Blazor List of components, shift values from components when removed from list

我正在尝试了解我在 blazor 3.1 中遇到的这个问题,感谢任何可以向我解释的人。

例如:
[真] [假] [假]
删除列表中的第一项(本例中为真)给出
[真] [假]
我在期待
[假] [假]

如果组件重新初始化或其他原因,如果所有布尔值都为假,我会理解,但这种行为让我感到难过。

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; }

    }
}

在另一个项目中,我使用 Radzen Dropdown 多 select 组件和来自右侧组件的 selected 项目 shift/merge。 例如:
[selected:1] [selected:2,3]
我删除了第一个组件,结果是
[selected:1,2,3]

删除右侧的组件不会更改左侧的组件。
我的目标是让用户能够动态地添加和删除组件。 也许我的整个方法是错误的...任何建议表示赞赏

在循环内的组件上使用 @key。这有助于渲染引擎了解更新了哪些元素。

<MyComponent @key=@item ThisItem="@item" Close="close" />

Index.razor

<h1>List Component Issue</h1>

<div style="display:flex; flex-direction:row;">
    @foreach (var item in listOfItems)
    {
        <MyComponent @key=@item ThisItem="@item" OnClose="OnCloseClicked" />
    }
</div>

Index.razor.cs

public partial class Index
{
    private List<Item> listOfItems;

    public Index()
    {
        listOfItems = new(5)
        {
           new() {Id = "1", Title = "First"},
           new() {Id = "2", Title = "Second"},
           new() {Id = "3", Title = "Third"},
           new() {Id = "4", Title = "Fourth"},
           new() {Id = "5", Title = "Fifth"}
        };
    }

    public void OnCloseClicked(Item itemToRemove)
        => listOfItems.Remove(itemToRemove);
}

MyComponent.razor

<div>
    <div style="margin:5px;">
        @ThisItem.Title is @isSomething
    </div>
    <div>
        <button @onclick=ToggleBool>Toggle</button>
        <button @onclick=CloseToParent>close</button>
    </div>
</div>

@code {
    private bool isSomething;

    [Parameter]
    public Item ThisItem { get; set; }

    [Parameter]
    public EventCallback<Item> OnClose { get; set; }

    private void ToggleBool() => isSomething = !isSomething;

    public async Task CloseToParent() => await OnClose.InvokeAsync(ThisItem);
}

@key Docs

我想知道这是否是经典的 c# lambda 捕获问题。尝试

@foreach (var item in listOfItems)
{  
    var temp = item;
    <MyComponent ThisItem="@temp" Close="close"></MyComponent>
}