You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:36:08