Blazor Server .NET8中关闭MudDialog后重新渲染Razor页面
问题描述
我有一个主页面Transact.razor,页面内有一个名为Add New的按钮,点击后会打开MudDialog(AddTransact.razor)用于添加新交易。关闭该对话框后,我希望重新渲染Transact页面,使新增交易显示在页面表格中。
使用Blazor Server端.NET8框架,需要实现重渲染而非刷新页面,保留SPA优势。
现有尝试代码如下:
Transact.razor代码
private async Task AddNew() { var options = new DialogOptions { ClassBackground = "my-custom-class", CloseOnEscapeKey = true, MaxWidth = MaxWidth.Medium, FullWidth = true, NoHeader = true }; var dialog = DialogService.Show<AddTransact>("Add New", options); var result = await dialog.Result; if (!result.Cancelled) { await vwTranService.GetAllVwTransactions(); StateHasChanged(); } }
AddTransact.razor(对话框)代码
private async void Submit() { if(selectedUser is not null) { isVisible = true; await Task.Delay(1000); Transaction!.UserID = selectedUser?.id; Transaction!.DOCUMENT_NUM = DocumentNumber; Transaction.CREATED_DATE = DateValue; Transaction.PARTICULARS = Particulars; Transaction.AMOUNT = Amount; if (Amount > selectedUser!.Balance) { Snackbar.Add("User does not have enough balance.", Severity.Error); return; } Balance!.UserID = selectedUser?.id; Balance.Balance -= Amount; await tranService.AddTransactionAsync(Transaction); await balanceService.UpdateBalance(Balance); Snackbar.Add("Transaction added successfully", Severity.Success); Transaction = new(); selectedUser = new(); users = new(); await vwUserService.GetAllUsers(); await GenerateDocumentNumberAsync(); Amount = 0; Particulars = string.Empty; Balance = new(); isVisible = false; StateHasChanged(); return; } Snackbar.Add("Please select a user", Severity.Warning); }
但当前方案并未生效。
解决方案
1. 修复对话框提交方法(AddTransact.razor)
核心问题是Submit用了async void,导致异步操作无法被框架正确跟踪,且未主动关闭对话框返回结果。修改如下:
// 将async void改为async Task private async Task Submit() { if(selectedUser is not null) { isVisible = true; await Task.Delay(1000); Transaction!.UserID = selectedUser?.id; Transaction!.DOCUMENT_NUM = DocumentNumber; Transaction.CREATED_DATE = DateValue; Transaction.PARTICULARS = Particulars; Transaction.AMOUNT = Amount; if (Amount > selectedUser!.Balance) { Snackbar.Add("User does not have enough balance.", Severity.Error); return; } Balance!.UserID = selectedUser?.id; Balance.Balance -= Amount; await tranService.AddTransactionAsync(Transaction); await balanceService.UpdateBalance(Balance); Snackbar.Add("Transaction added successfully", Severity.Success); // 提交成功后关闭对话框,返回成功结果 Dialog.Close(DialogResult.Ok(true)); // 重置表单(可选) Transaction = new(); selectedUser = new(); users = new(); await vwUserService.GetAllUsers(); await GenerateDocumentNumberAsync(); Amount = 0; Particulars = string.Empty; Balance = new(); isVisible = false; return; } Snackbar.Add("Please select a user", Severity.Warning); }
2. 确保主页面更新绑定数据源(Transact.razor)
原代码仅调用了获取数据的方法,但未将结果赋值给表格绑定的变量。假设表格绑定的是transactions列表,修改如下:
// 定义表格绑定的数据源变量 private List<VwTransaction> transactions = new(); private async Task AddNew() { var options = new DialogOptions { ClassBackground = "my-custom-class", CloseOnEscapeKey = true, MaxWidth = MaxWidth.Medium, FullWidth = true, NoHeader = true }; var dialog = DialogService.Show<AddTransact>("Add New", options); var result = await dialog.Result; if (!result.Cancelled) { // 将新数据赋值给绑定变量,触发Blazor自动渲染 transactions = await vwTranService.GetAllVwTransactions(); // 无需手动调用StateHasChanged,变量赋值后框架会自动处理 } }
3. 表格绑定验证
确保表格组件正确绑定到更新后的数据源:
<MudTable Items="@transactions" Hover="true" Bordered="true"> <!-- 列定义示例 --> <HeaderContent> <MudTh>交易编号</MudTh> <MudTh>用户</MudTh> <MudTh>金额</MudTh> </HeaderContent> <RowTemplate> <MudTd>@context.DOCUMENT_NUM</MudTd> <MudTd>@context.UserName</MudTd> <MudTd>@context.AMOUNT</MudTd> </RowTemplate> </MudTable>
关键注意点
- 禁用
async void:Blazor中组件方法使用async void会导致异步操作失控,统一用async Task替代。 - 主动关闭对话框:必须调用
Dialog.Close(DialogResult.Ok(...)),让主页面感知到提交成功,触发后续数据更新。 - 数据源赋值触发渲染:Blazor会自动检测绑定变量的变化并触发重渲染,只要确保新数据正确赋值给绑定变量,无需手动调用
StateHasChanged()。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

