参数/级联参数不更新对象

Parameter / CascadingParameter not updating object

我想在传递 EventCallback 的子组件 TodoComponent 中更新 TodoItem

在我的 TodoPage.razor.cs 中,我实现了一个更新方法:

public async void UpdateTodo(TodoItem todoItem)
{
    await Http.PutAsJsonAsync("todo", todoItem);
    await RefreshTodos();
}

然后我试图传递给负责渲染对象的TodoComponent

@foreach (var item in @TodoItems)
{
    <div class="row">
            <CascadingValue Value=@item Name="TodoItem">
                <TodoComponent UpdateCallback="@(async () => UpdateTodo(item))">
                </TodoComponent>
            </CascadingValue>
    </div>
}

TodoComponent.razor

@inherits ListOfTodos.Client.Components.TodoComponentBase
<div class="input-group col-12">
    <div class="input-group-prepend">
        <div class="input-group-text">
            <input type="checkbox" @bind="@TodoItem.IsDone" onclick="@UpdateCallback">
        </div>
    </div>

    <div class="col-8">
        <input type="text" class="form-control" @bind="@TodoItem.TaskName" oninput="@UpdateCallback" />
    </div>

    <div class="input-group-append">
        <input type="date" @bind="@TodoItem.DueDate" />
    </div>
</div>

附加信息:

public async Task RefreshTodos()
{
    TodoItems = await Http.GetFromJsonAsync<List<TodoItem>>("todo");
    StateHasChanged();
}
public class TodoComponentBase : ComponentBase
{
    [CascadingParameter(Name = "TodoItem")]
    public TodoItem TodoItem { get; set; }

    [Parameter]
    public EventCallback<TodoItem> UpdateCallback { get; set; }

    protected override Task OnInitializedAsync()
    {
        return base.OnInitializedAsync();
    }

}

当我通过 onchangeoninput 调用 UpdateCallback 时,TodoItem 就像根本没有更新一样,我不知道'知道绑定是否按照我的预期工作。

如何正确地将对象传递给子组件并使其正确更新?

这是 github 存储库:https://github.com/DgoNeves/Blazor.ListOfTodos 它在内存中工作,因此您不需要任何数据库来 运行 它。

编辑:我不完全知道为什么会这样,但显然控制器调用是出于某种原因。

好的,我刚知道你的问题。这是你的 UpdateTodo 方法 :
异步方法必须 return 一个任务或一个 ValueTask。使用 :

更新您的代码
public async Task UpdateTodo(TodoItem todoItem)
{
    await Http.PutAsJsonAsync("todo", todoItem);
    await RefreshTodos();
}

我想通了!

@bind="@TodoItem.TaskName"默认执行onChange

onInput 显然发生在 onChange 之前所以在屏幕截图中当我在它后面得到 1 个字符时意味着它没有更新 TodoItem.TaskName 因为那是下一步。

如果我真的想在每次击键时调用 API,我需要将其更改为:

@bind-value="@TodoItem.TaskName" @bind-value:event="oninput" onchange="@UpdateCallback"

通过这种方式,我改变了发生的绑定 onInput 我调用了 UpdateCallback onChange。 因为 onInput happens first 我在 onChange 上获得了更新值,因此传递了正确的值。

我发现这个的来源:https://github.com/dotnet/aspnetcore/issues/15554 他的错误跟我一模一样