如何封装组件解决表单双击重复提交问题?基于Radzen与ASP.NET Core
封装防重复提交组件适配Radzen表单
问题背景
表单双击引发的重复提交是高频并发问题,未做防护时很容易出现。现有基础方案通过_busy状态控制按钮禁用和提交拦截,但每次都重复编写这套逻辑过于繁琐,需要封装成可复用组件。
封装实现步骤
1. 创建通用防重复提交按钮组件
新建SubmitButton.razor组件,将忙碌状态管理、防重复逻辑统一封装:
<button disabled="@IsBusy" @onclick="HandleSubmit" class="rz-button rz-button-primary"> @(IsBusy ? "提交中..." : ButtonText) </button> @code { // 可自定义按钮显示文本 [Parameter] public string ButtonText { get; set; } = "提交"; // 接收外部传入的表单提交逻辑 [Parameter] public Func<Task> OnSubmit { get; set; } private bool IsBusy { get; set; } private async Task HandleSubmit() { // 忙碌状态或无提交逻辑时直接返回,拦截重复请求 if (IsBusy || OnSubmit == null) return; IsBusy = true; try { // 执行外部传入的提交操作 await OnSubmit(); } finally { // 无论提交成功或失败,都重置忙碌状态 IsBusy = false; } } }
2. 在Radzen表单中复用组件
替换原有的Radzen提交按钮,直接传入表单的提交方法即可:
<RadzenForm @ref="form" Submit="FormSubmit"> <!-- 表单字段示例 --> <RadzenTextBox @bind-Value="FormModel.Name" Label="姓名" /> <RadzenEmail @bind-Value="FormModel.Email" Label="邮箱" /> <!-- 使用封装的防重复提交按钮 --> <SubmitButton ButtonText="提交表单" OnSubmit="form.Submit" /> </RadzenForm> @code { private RadzenForm form; private UserFormModel FormModel { get; set; } = new(); private async Task FormSubmit() { // 原有表单验证与提交逻辑 if (form.Validate()) { // 调用后端接口保存数据 await UserService.SaveUser(FormModel); // 提交成功后的操作,如提示信息、页面跳转 } } public class UserFormModel { public string Name { get; set; } public string Email { get; set; } } }
3. 适配Radzen风格的扩展(可选)
如果需要让按钮更贴合Radzen的UI风格,可以添加加载动画:
<button disabled="@IsBusy" @onclick="HandleSubmit" class="@($"rz-button {ButtonClass}")"> @if (IsBusy) { <span class="rz-spinner rz-spinner-sm"></span> <span class="ml-2">提交中...</span> } else { @ButtonText } </button> @code { // 新增自定义样式参数,适配Radzen按钮样式 [Parameter] public string ButtonClass { get; set; } = "rz-button-primary"; // 其他逻辑保持不变 }
核心逻辑说明
- 组件内部维护
IsBusy状态,点击时自动拦截重复提交请求 - 通过
try-finally确保无论提交结果如何,状态都会重置,避免按钮长期禁用 - 利用组件参数传递提交逻辑,无需在每个表单中重复编写状态判断代码
内容的提问来源于stack exchange,提问作者Varin
相关产品推荐
相关产品推荐

