Blazor表单提交时Model重置,@Code代码块重复执行问题
问题分析与解决方案
你遇到的核心问题是点击提交按钮后组件被重新初始化(OnInitialized再次执行),导致产品数量被重置,这本质是因为表单触发了整页刷新,而非Blazor的客户端事件处理。以下是具体原因和修复步骤:
原因1:HTML元素ID重复
你的foreach循环中,所有InputNumber和对应的label都使用了相同的id="quantity",违反了HTML中ID必须唯一的规则。浏览器无法正确识别表单元素,可能导致Blazor的表单拦截逻辑失效,触发传统表单提交进而整页刷新。
原因2:事件处理方法类型问题
使用void类型的事件处理方法,在某些场景下Blazor无法确保阻止默认的表单提交行为,也会导致整页刷新。
修复步骤
1. 修复重复的ID问题
修改foreach中的label和InputNumber,为每个元素生成唯一ID:
@foreach (var product in products) { <tr> <td> <label for="@($"quantity-{product.Name}")">Quantity</label> <InputNumber id="@($"quantity-{product.Name}")" min="0" @bind-Value="@product.Quantity"> </InputNumber> </td> </tr> }
2. 修改事件处理方法为异步Task类型
将CheckOutTickets改为async Task类型,确保Blazor正确拦截默认提交:
private async Task CheckOutTickets(EditContext obj) { // 处理你的业务逻辑,直接使用更新后的products即可 var updatedProducts = products; // 示例:输出更新后的数量 foreach (var product in updatedProducts) { Console.WriteLine($"{product.Name}: {product.Quantity}"); } await Task.CompletedTask; // 即使无异步操作,也需返回CompletedTask }
3. 可选:移除StreamRendering属性(若不需要)
[StreamRendering]主要用于Blazor Server的流式渲染,若你的场景不需要,可以尝试移除该属性,避免潜在的渲染异常:
// @attribute [StreamRendering] 注释或删除这一行
验证效果
修复后,点击提交按钮时:
- 只会执行
CheckOutTickets方法,不会触发OnInitialized products中的数量会保留你在UI中修改的值,可直接在CheckOutTickets中使用更新后的上下文
内容的提问来源于stack exchange,提问作者Simsons
相关产品推荐
相关产品推荐

