Blazor组件右键操作后无法刷新问题求助
问题分析与解决方案
核心问题
- 变量名不匹配:声明的列表变量是
assignedCalls,但数据加载和更新时都用了assignedWork,导致UI绑定的数据源从未被更新。 - 异步操作上下文错误:使用
Task.Run脱离Blazor同步上下文,异步操作完成后未正确触发UI更新;且OnMenuItemClick中InvokeAsync(StateHasChanged)在异步任务完成前执行,此时数据尚未刷新。 - 不必要的Task.Run:事件处理程序可以用
async void直接执行异步逻辑,无需额外开启后台线程。
修复步骤
- 统一变量名:将所有
assignedWork替换为assignedCalls,确保数据源和UI绑定一致。 - 修改菜单回调为异步:将
OnMenuItemClick改为async void,移除Task.Run,直接await服务调用和数据刷新方法。 - 正确触发状态更新:在异步操作完成后,通过
InvokeAsync(StateHasChanged)通知Blazor更新UI。
修改后的完整代码
@code { [Parameter] public string? SelectedCrewMemberId { get; set; } [Parameter] public string? SelectedCallId { get; set; } [Parameter] public DateTime FromDate { get; set; } [Parameter] public DateTime ToDate { get; set; } List<AssignedCallDto> assignedCalls = new List<AssignedCallDto>(); List<string> selectedAssignedCallIds = new List<string>(); bool loading = false; protected override async Task OnParametersSetAsync() { await base.OnParametersSetAsync(); if (loading) { return; } if (SelectedCrewMemberId is not null) { try { loading = true; assignedCalls = await actionCallService.GetAssignedCallsByEmployeeId(SelectedCrewMemberId, FromDate, ToDate); } finally { loading = false; } } } public async Task UpdateDispatchBoard() { assignedCalls = await actionCallService.GetAssignedCallsByEmployeeId(SelectedCrewMemberId, FromDate, ToDate); } void ShowContextMenuWithItems(MouseEventArgs args, string visitId, string status, string nextStatus, string visitType) { var contextMenuItems = new List<ContextMenuItem>(); if (status != ACTION_STATUS.ActionCompleted) { var value = (visitId, status, visitType, nextStatus); contextMenuItems.Add(new ContextMenuItem() { Text = nextStatus, Value = value }); ContextMenuService.Open(args, contextMenuItems, OnMenuItemClick); } } async void OnMenuItemClick(MenuItemEventArgs args) { var param = (string VisitId, string Status, string VisitType, string NextStatus)args.Value; try { switch (args.Text) { case "In Progress": await actionCallService.InProgressCall(SelectedCrewMemberId, param.VisitId, param.VisitType, param.Status, FromDate, ToDate); break; case "Acknowledged": await actionCallService.AcknowledgeCall(SelectedCrewMemberId, param.VisitId, param.Status, FromDate, ToDate); break; case "Completed": await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate); break; case "Rejected": await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate); break; default: break; } await UpdateDispatchBoard(); // 通知UI更新 await InvokeAsync(StateHasChanged); } finally { ContextMenuService.Close(); } } }
额外说明
- Blazor中,组件的状态更新需要在同步上下文中触发,
async void作为事件处理程序是允许的,Blazor会自动处理上下文切换。 - 统一变量名是关键,之前的笔误导致数据源从未被正确赋值,这是列表不刷新的首要原因。
- 将
ContextMenuService.Close()放在finally块中,确保无论操作成功与否,菜单都会关闭。
内容的提问来源于stack exchange,提问作者user2661305
相关产品推荐
相关产品推荐

