Blazor循环生成元素时点击事件参数传递错误问题
Blazor循环中点击事件传递错误参数的原因与解决方法
问题原因
这是闭包捕获变量的经典陷阱:你绑定的点击事件lambda表达式() => PlayUrl(counter)并没有捕获循环执行时counter的当前数值,而是捕获了counter变量的内存引用。
当循环执行完毕后,counter已经完成了两次递增(初始值1,循环两次后变成3)。等到用户点击任何一个span元素时,lambda才会去读取counter的当前值,自然每次都是3。
解决方法
方法一:在循环内创建局部变量保存当前值
在循环内部定义一个局部变量,把当前counter的值存进去,让lambda捕获这个局部变量(每个循环迭代的局部变量都是独立的,不会共享引用):
@{ counter = 1; } @foreach(string str in strings) { var currentNum = counter; <div> <span @onclick="() => PlayUrl(currentNum)">@counter</span> <span>@str</span> </div> counter++; } @code { private int counter = 1; private string[] strings = { "aaa", "bbb" }; private void PlayUrl(int audioId) { // 此处编写播放MP3的逻辑,比如加载对应audioId的MP3文件 } }
方法二:利用循环索引替代独立计数器
直接通过Select给每个字符串绑定对应的索引(+1对应你的1、2、3命名规则),避免维护额外的计数器变量:
@foreach(var item in strings.Select((text, idx) => new { Text = text, AudioId = idx + 1 })) { <div> <span @onclick="() => PlayUrl(item.AudioId)">@item.AudioId</span> <span>@item.Text</span> </div> } @code { private string[] strings = { "aaa", "bbb" }; private void PlayUrl(int audioId) { // 此处编写播放MP3的逻辑 } }
这两种方法都能让点击事件正确传递对应MP3文件的编号,避免闭包引用共享导致的参数错误。
内容的提问来源于stack exchange,提问作者Lasse Michael Mølgaard
相关产品推荐
相关产品推荐

