在 Blazor 中更改绑定到组件的模型时更新 UI

Jim*_*tar 4 asp.net-core blazor blazor-webassembly asp.net-core-5.0

我创建了代码的简化版本来演示我遇到的问题。我有一个自定义 Blazor 组件 TestComponent.razor:

@{ int index = 0; }
@foreach (var option in _value)
{
    <input id="@index" type="checkbox" @bind="@option.Selected" /><label for="@index">@option.Name</label>
    index++;
}

@code {
    [Parameter] public EventCallback<TestModel[]> ValueChanged { get; set; }
    private TestModel[] _value;
    [Parameter] public TestModel[] Value
    {
        get => _value;
        set
        {
            if (_value == value) return;
            _value = value;
            ValueChanged.InvokeAsync(value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个基本模型 TestModel.cs:

public class TestModel
{
    public string Name { get; set; }
    public bool Selected { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的页面只是将 TestModel 的数组绑定到 TestComponent 并显示所有选定的选项:

@page "/"

<TestComponent @bind-Value="testOptions" />
@foreach (var option in testOptions)
{
    if (option.Selected)
    {
        <p>@option.Name</p>
    }
}

@code {
    private TestModel[] testOptions = new TestModel[]
    {
        new TestModel() { Name = "Amy", Selected = true },
        new TestModel() { Name = "Bob", Selected = false }
    };
}
Run Code Online (Sandbox Code Playgroud)

加载页面时,我会得到所选选项的列表。当我选中/取消选中任何选项时,我可以看到模型更新(我添加了一个将模型写入控制台的按钮),但 UI 未更新。请有人告诉我在让 UI 更新所选选项列表时缺少什么?

Jim*_*tar 5

感谢杰森帮助我找到了解决方案。我通过将 StateHasChanged() 添加到新创建的 OnChangeAsync 方法来实现此工作。这需要一些调整,因为我的模型是一个数组,每个复选框仅更改该数组的一个成员。

新的 TestComponent.razor:

    @for (int i = 0; i < _value.Length; i++)
    {
        int index = i;
        <input id="@index" type="checkbox" checked="@_value[index].Selected" @onchange="async args => { await OnChangeAsync(args, index); }" /><label for="@index">@_value[index].Name</label>
    }
    
    @code {
        [Parameter] public EventCallback<TestModel[]> ValueChanged { get; set; }
        private TestModel[] _value;
        [Parameter] public TestModel[] Value
        {
            get => _value;
            init => _value = value;
        }
    
        public async Task OnChangeAsync(ChangeEventArgs args, int index)
        {
            _value[index].Selected = (bool)args.Value;
            await ValueChanged.InvokeAsync(_value);
            StateHasChanged();
        }
    }
Run Code Online (Sandbox Code Playgroud)