提取Blazor MAUI组件后列表无法更新的问题排查
.NET MAUI Blazor 组件拆分后数据绑定异常问题
我正在尝试用.NET MAUI结合Blazor开发应用,将表格行代码提取为独立组件后遇到了数据绑定问题。
现有Expense类定义
public class Expense { public DateTime Date { get; set; } public decimal Amount { get; set; } public string Note { get; set; } public Expense(DateTime date, decimal amount, string note) { Date = date; Amount = amount; Note = note; } }
单组件时功能正常的代码
当所有逻辑都在单个Blazor组件中处理Expense列表时,功能完全正常:
组件HTML部分
<button class="btn btn-primary bg-color-green" @onclick="AddExpense"><i class="oi oi-plus"></i></button> <table class="table"> <thead> <tr> <th>Date</th> <th>Amount</th> <th>Note</th> <th></th> </tr> </thead> <tbody> @for (var i = 0; i < expenses.Count; i++) { int copy = i; <tr> <td> <input type="date" min="2022-01-01" max="@currentDay" @bind="@expenses[copy].Date" @bind:format="yyyy-MM-dd" /> </td> <td> <input type="number" min="0" step="0.01" @bind="@expenses[copy].Amount" /> </td> <td> <input type="text" @bind="@(expenses[copy].Note)" /> </td> <td> <button class="btn" @onclick="() => expenses.RemoveAt(copy)"><i class="oi oi-delete"></i></button> </td> </tr> } </tbody> </table>
@code区域代码
private readonly string currentDay = $"{DateTime.Now.Year}-{DateTime.Now.Month}-{DateTime.Now.Day}"; private List<Expense> expenses = new List<Expense>() { new Expense(DateTime.Today, 100, "test") }; private void AddExpense() { expenses.Add(new Expense(DateTime.Today, 0, "")); }
拆分后的ExpenseRow组件
将表格行提取为独立的ExpenseRow组件后,出现了问题:
ExpenseRow组件HTML部分
<tr> <td> <input type="date" min="@MinAttributeValue" max="@MaxAttributeValue" @bind="@Date" @bind:format="yyyy-MM-dd"/> </td> <td> <input type="number" min="0" step="0.01" @bind="@Amount"/> </td> <td> <input type="text" @bind="@Note"/> </td> <td> <button class="btn" @onclick="() => OnRemoveClick()"><i class="oi oi-delete"></i></button> </td> </tr>
ExpenseRow组件@code区域代码
private string MinAttributeValue => Min.ToString("yyyy-MM-dd"); private string MaxAttributeValue => Max?.ToString("yyyy-MM-dd"); [Parameter] public DateTime Min { get; set; } = new DateTime(2022, 1, 1); [Parameter] public DateTime? Max { get; set; } [Parameter] public DateTime Date { get; set; } [Parameter] public EventCallback<DateTime> DateChanged { get; set; } [Parameter] public decimal Amount { get; set; } [Parameter] public EventCallback<decimal> AmountChanged { get; set; } [Parameter] public string Note { get; set; } [Parameter] public EventCallback<string> NoteChanged { get; set; } [Parameter] public Action OnRemoveClick { get; set; }
修改后的原组件代码
原组件更新为在for循环中渲染ExpenseRow组件:
<table class="table"> <thead> <tr> <th>Date</th> <th>Amount</th> <th>Note</th> <th></th> </tr> </thead> <tbody> @for (var i = 0; i < expenses.Count; i++) { int copy = i; <ExpenseRow @bind-Amount="expenses[copy].Amount" @bind-Date="expenses[copy].Date" @bind-Note="expenses[copy].Note" Max="@DateTime.Today" OnRemoveClick="() => { expenses.RemoveAt(copy); StateHasChanged(); }" /> } </tbody> </table>
出现的问题
拆分后数据绑定被破坏,存在以下问题:
- 列表中各项的属性无法更新,切换字段或添加新项后输入的值会被还原;
- 删除按钮点击后无法移除行,添加
StateHasChanged()调用后该问题得到修复;
我尝试在各Changed事件中添加StateHasChanged(),但未解决添加新项时值被还原的问题:
int copy = i; <ExpenseRow @bind-Amount="expenses[copy].Amount" AmountChanged="() => StateHasChanged()" @bind-Date="expenses[copy].Date" DateChanged="() => StateHasChanged()" @bind-Note="expenses[copy].Note" NoteChanged="() => StateHasChanged()" Max="@DateTime.Today" OnRemoveClick="() => { expenses.RemoveAt(copy); StateHasChanged(); }" />
内容的提问来源于stack exchange,提问作者Chris Thompson
相关产品推荐
相关产品推荐

