Blazor中@foreach循环绑定数组索引时输入值被覆盖的问题及解决方法
问题原因分析
你遇到的问题是闭包捕获导致的变量引用共享。在你的@foreach循环里,手动维护的index变量被所有输入框的绑定表达式捕获了同一个引用。当循环结束后,index的值已经变成了2(因为你有两个输入项,每次遇到IsInput=true就会执行index++),但你的userInputBind列表只有2个元素(索引0和1)。更关键的是,所有输入框的绑定实际上都指向了index变量的当前值,最终导致两个输入框都绑定到了userInputBind[1],所以你输入的内容会同步到同一个位置,两个元素自然都显示最后输入的"string2"。
另外,你的代码里还有个小错误:else块里用了@item.Text,但循环变量是userInput,应该改成@userInput.Text,否则会报错。
修复方案
下面提供两种可行的修复方式,你可以根据习惯选择:
方案1:使用for循环替代foreach
for循环的迭代变量是每次独立的,能避免闭包捕获同一个变量的问题,同时我们可以更清晰地控制输入索引:
@{ int inputIndex = 0; } @for (int i = 0; i < myList.Count; i++) { var userInput = myList[i]; if (userInput.IsInput) { <input @bind="userInputBind[inputIndex]"/> // 确保不超出userInputBind的长度 if (inputIndex < userInputBind.Count - 1) { inputIndex++; } } else { <p>@userInput.Text</p> } } @code { public List<UserInput> myList = new List<UserInput> { new UserInput { IsInput = false, Text = "One" }, new UserInput { IsInput = false, Text = "Two" }, new UserInput { IsInput = true, Text = "" }, new UserInput { IsInput = false, Text = "Four" }, new UserInput { IsInput = true, Text = "" }, new UserInput { IsInput = false, Text = "Six" } }; public List<string> userInputBind = new List<string> { "", "" }; public class UserInput { public bool IsInput { get; set; } public string Text { get; set; } } }
方案2:在foreach中捕获当前输入索引
如果坚持使用foreach,可以在每次遇到输入项时,把当前的inputIndex值保存到一个局部变量中,让绑定表达式捕获这个局部变量(而不是共享的inputIndex):
@{ int inputIndex = 0; } @foreach (var userInput in myList) { if (userInput.IsInput) { // 捕获当前的输入索引到局部变量 var currentInputIndex = inputIndex; <input @bind="userInputBind[currentInputIndex]"/> if (inputIndex < userInputBind.Count - 1) { inputIndex++; } } else { <p>@userInput.Text</p> } } @code { // 保持原有的myList、userInputBind和UserInput类不变 public List<UserInput> myList = new List<UserInput> { new UserInput { IsInput = false, Text = "One" }, new UserInput { IsInput = false, Text = "Two" }, new UserInput { IsInput = true, Text = "" }, new UserInput { IsInput = false, Text = "Four" }, new UserInput { IsInput = true, Text = "" }, new UserInput { IsInput = false, Text = "Six" } }; public List<string> userInputBind = new List<string> { "", "" }; public class UserInput { public bool IsInput { get; set; } public string Text { get; set; } } }
这两种方式都能确保每个输入框绑定到userInputBind的正确索引,输入"string1"和"string2"后,userInputBind会正确保存{"string1", "string2"}。
内容的提问来源于stack exchange,提问作者Ronaksse
相关产品推荐
相关产品推荐

