Blazor复选框组传递错误索引值问题排查
Blazor复选框组for循环索引值异常问题解决
我在用Blazor开发应用时,需要实现一个复选框组,用for循环渲染选项列表:
@for (int i = 0; i < Choices?.Count(); i++) { <div class="checkbox-option"> <input type="checkbox" id="Name" name="Name" value="@(i + 1)" @onchange="eventArgs => { CheckChanged(i, eventArgs.Value); } "> <label for="@($"{ElementData.Name}-{i}")">@Choices[i]</label> </div> } @code { void CheckChanged(int index, object checkValue) { var i = item; } }
运行后发现,所有复选框触发CheckChanged时,index参数始终是Choices的总数,不是对应选项的索引。
问题原因
这是闭包捕获循环变量的经典陷阱:事件委托@onchange中的lambda表达式捕获的是循环变量i的引用,而非循环时的当前值。当循环执行完毕后,i的值已经变成了循环结束的边界值(即Choices.Count()),此时所有复选框的事件委托触发时,都会读取这个已经更新后的i值,导致索引全部异常。
解决方案
在循环内部创建一个局部变量,保存当前循环的i值,让每个事件委托捕获这个局部变量的独立实例:
@for (int i = 0; i < Choices?.Count(); i++) { var rtn = i; // 新增局部变量保存当前索引 <div class="checkbox-option"> <input type="checkbox" id="Name" name="Name" value="@(i + 1)" @onchange="eventArgs => { CheckChanged(rtn, eventArgs.Value); } "> <label for="@($"{ElementData.Name}-{i}")">@Choices[i]</label> </div> } @code { void CheckChanged(int index, object checkValue) { var i = item; } }
这样每个循环迭代中,rtn都是独立的变量,存储了当前迭代的索引值,事件委托捕获的是这个独立变量的引用,触发时就能拿到正确的索引。
内容的提问来源于stack exchange,提问作者Enrico
相关产品推荐
相关产品推荐

