为什么当我从绑定到组件的列表中删除项目时,它会从列表中删除正确的项目,但会重复最后一个项目

Yar*_*mar 1 c# components blazor

我在 Blazor 服务器应用程序中有一个奇怪的行为。

当我有一个对象列表并删除列表中的一个项目时,它会删除列表中的正确项目,但会将数据从最后一项复制到前面的一项。

仅当我将列表数据绑定到我自己的组件时才会发生这种情况。如果我将它直接绑定到输入元素,则不会发生这种情况。

我在一个小代码示例中重现了该行为,如下所示,只需尝试删除第二个项目并查看该行为。

谢谢谁能帮忙...

Blazor 标记

 <table>
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (User user in _users)
        {
            <tr>
                <td><MyText @bind-Value="user.Id"></MyText></td>
                <td><MyText @bind-Value="user.Name"></MyText></td>
                <td @onclick="(() => DeleteUser(user))">delete</td>
            </tr>
        }
    </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

Blazor 代码

private List<User> _users = new List<User>();
private class User
{
    public string Id { get; set; } = "";
    public string Name { get; set; } = "";
}

protected override void OnInitialized()
{
    _users.Add(new User() { Id = "1", Name = "Adam" });
    _users.Add(new User() { Id = "2", Name = "Benny" });
    _users.Add(new User() { Id = "3", Name = "Charles" });
    _users.Add(new User() { Id = "4", Name = "David" });
    base.OnInitialized();
}

private void DeleteUser(User user)
{
    _users.Remove(user);
}
Run Code Online (Sandbox Code Playgroud)

我的文本组件

<input @bind-value="@Value" />

@code {

    public string _value = "";

    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    [Parameter]
    public string Value
    {
        get
        {
            return _value;
        }
        set
        {
            if (_value != value)
            {
                _value = value;
                ValueChanged.InvokeAsync(value);
            }
        }
    }    
}
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 5

您必须为 Blazor 的“差异引擎”提供一点帮助。@key像这样使用:


@foreach (User user in _users)
{
    <tr @key="user">
        <td><MyText @bind-Value="user.Id"></MyText></td>
        <td><MyText @bind-Value="user.Name"></MyText></td>
        <td @onclick="(() => DeleteUser(user))">delete</td>
    </tr>
}

Run Code Online (Sandbox Code Playgroud)