Blazor Server:点击按钮后立即显示加载文本的解决方法
解决方案
问题根源在于async void的使用和异步调用未正确等待,导致UI状态更新被延迟。以下是修改后的代码:
页面UI部分
<AuthorizeView> <Authorized> @if (IsLoading) { <div>Loading</div> } else { <div class="add-user"> <PageHeader Text="Add User" /> <form Model="NewUser" class="user-form"> <div class="line"> <label for="name">Name</label> <input type="text" id="name" @bind="NewUser.Name" /> </div> <div class="line"> <label for="email">Email</label> <input type="email" id="email" @bind="NewUser.Email" /> </div> <div class="line"> <div> <label>Gender</label> </div> <div> <label for="male">Male</label> <input type="radio" id="male" name="gender" value="Male" @onchange="UpdateGender" checked="@IsMaleRadioButtonChecked" /> <label for="female">Female</label> <input type="radio" id="female" name="gender" value="Female" @onchange="UpdateGender" checked="@IsFemaleRadioButtonChecked"/> </div> </div> <div class="line"> <label for="date-of-birth">Date of Birth</label> <input type="date" id="date-of-birth" @bind="NewUser.DateOfBirth" /> </div> <Button Text="Add User" OnClick="Save" /> </form> </div> } </Authorized> </AuthorizeView>
@code部分修改
@code { private bool IsLoading { get; set; } = false; // 关键:将async void改为async Task private async Task Save() { IsLoading = true; StateHasChanged(); try { if (!AreFormValuesValid()) return; NewUser.Id = 0; NewUser.Password = NewUser.Name; NewUser.Role = roleService.Get("Participant"); NewUser.Gender = Gender == "Male" ? Enumerations.Gender.Male : Enumerations.Gender.Female; if (await userService.AddOrUpdate(NewUser)) { await js.InvokeVoidAsync("alert", "User Added Successfully"); NewUser = new User(); Gender = ""; } else { await js.InvokeVoidAsync("alert", "Couldn't Save User"); } } finally { IsLoading = false; StateHasChanged(); } } // 其他已有代码(如AreFormValuesValid、UpdateGender等)保持不变 }
核心修改点说明
- 替换async void为async Task:Blazor事件处理方法必须返回
async Task才能正确同步UI更新,async void会脱离Blazor同步上下文,导致状态更新延迟或失效。 - await所有异步调用:包括
js.InvokeVoidAsync,确保弹窗完成后再执行后续逻辑,避免加载状态被提前关闭。 - 使用try/finally:保证无论操作成功、失败还是抛出异常,加载状态都会被重置,避免UI一直停留在加载状态。
- 手动触发StateHasChanged:设置
IsLoading=true后手动调用,确保UI立刻响应状态变化。
内容的提问来源于stack exchange,提问作者TheOne
相关产品推荐
相关产品推荐

