Cod*_*eek 14 c# razor-pages blazor-server-side
我有下面的代码,但是当我单击该<tr>元素时传递的索引参数始终为 9。
这是因为表中有 9 行作为数据传递给组件。所以看起来索引总是最后设置的变量“i”的值...在这种情况下,foreach循环中最后一行之后的i的值是9,所以我在单击所有按钮时得到索引参数为9表中的行...
我的代码中的问题是什么,没有i为每行 onclick 设置值。
<table border="1">
@for(int i=0;i< ListData.DataView.Table.Rows.Count; i++)
{
<tr @onclick="(() => RowSelect(i))">
@foreach (ModelColumn col in ListData.ListColumns)
{
<td>@ListData.DataView.Table.Rows[i][col.Name]</td>
}
</tr>
}
</table>
Run Code Online (Sandbox Code Playgroud)
@code {
private async Task RowSelect(int rowIndex)
{
await ListRowSelected.InvokeAsync(rowIndex);
}
}
Run Code Online (Sandbox Code Playgroud)
xpo*_*ort 20
实际上你的问题是关于捕获局部变量的 lambda 。为了简单起见,请参阅以下使用控制台应用程序的模拟。
class Program
{
static void Main(string[] args)
{
Action[] acts = new Action[3];
for (int i = 0; i < 3; i++)
acts[i] = (() => Job(i));
foreach (var act in acts) act?.Invoke();
}
static void Job(int i) => Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud)
它将输出3, 3, 3三次而不是 0, 1, 2.
引用官方文档中有关EventCallback的内容:
<h2>@message</h2>
@for (var i = 1; i < 4; i++)
{
var buttonNumber = i;
<button class="btn btn-primary"
@onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@i
</button>
}
@code {
private string message = "Select a button to learn its position.";
private void UpdateHeading(MouseEventArgs e, int buttonNumber)
{
message = $"You selected Button #{buttonNumber} at " +
$"mouse position: {e.ClientX} X {e.ClientY}.";
}
}
Run Code Online (Sandbox Code Playgroud)
不要直接在 lambda 表达式中使用循环变量,例如
i前面的 for 循环示例。否则,所有 lambda 表达式都会使用相同的变量,这会导致所有 lambda 中使用相同的值。始终捕获局部变量中的变量值,然后使用它。在前面的示例中,循环变量 i 被分配给buttonNumber。
所以你需要制作一个本地副本,i如下所示。
@for(int i=0;i< ListData.DataView.Table.Rows.Count; i++)
{
int buffer=i;
<tr @onclick="(() => RowSelect(buffer))">
@foreach (ModelColumn col in ListData.ListColumns)
{
<td>@ListData.DataView.Table.Rows[i][col.Name]</td>
}
</tr>
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6704 次 |
| 最近记录: |