Blazor:@oninput使用越界索引,而不是 for 循环中的值

Blazor: @oninput uses out of bound index instead of value from the for loop

提问人:TomEberhard 提问时间:11/15/2023 更新时间:11/15/2023 访问量:43

问:

我正在尝试显示一个包含 8 行和 8 列的表,每个单元格都是一个映射到相应数组中值的输入。首次显示页面时,单元格中包含正确的值。

当我在输入单元格中输入一个数字以更新实际数组中的值时,行和列值是 8,而不是该单元格的相应值。

下面是 .razor 文件的相关部分:

<table class="table">
    <thead>
        <!--
        <tr>
            <th>Runs with</th>
            @foreach (var dog in dogList)
            {
                <th>@dog.name</th>
            }
        </tr>
        -->
    </thead>
    <tbody>
        <!-- The header, but not bold -->
        <tr>
            <td style="width:120px;">Runs with ↗️ </td>
            @foreach(Dog dog in dogList)
            {
                <td style="width:120px;">@dog.name</td>
            }
        </tr>
        @for(var row = 0; row<dogList.Count; row++)
        {
            <tr>
                <td style="width:120px;">@dogList[row].name</td>
                @for (var col = 0; col<dogList.Count; col++)
                {
                    <td style="width:120px;">
                        <input type="number" 
                            value="@dogSpeed[row][col]"
                            @oninput="@(e => {this.updateDogSpeed(row, col, e);})"
                        />
                    </td>
                    <!-- @oninput="@(e => {@dogSpeed[@row][@col] = double.Parse(e.Value.ToString());})" -->
                }
            </tr>
        }
    </tbody>

</table>

@code {
    public void updateDogSpeed(int row, int col, ChangeEventArgs e)
    {
        //dogSpeed[row][col] = double.Parse(e.Value.ToString());
        Console.WriteLine($"row={row}, col={col}, e.Value={e.Value}");
        //Console.WriteLine($"New value for dog speed[{row}][{col}]: {dogSpeed[row][col]} (e.Value={e.Value}");

    }
}

控制台输出显示 row=8, col=8, e.Value=(无论我输入什么新值,都很好)) 无论我更新哪个输入单元格,它都会打印出来。

我需要什么魔法咒语才能传入正确的行和列值?

我想以“正确”的方式做到这一点,而不求助于 JavaScript。我可以直接更新for循环中的dogSpeed数组,或者通过调用updateDogSpeed(row, col, newValue)来更新

C# HTML Blazor

评论


答:

1赞 NineBerry 11/15/2023 #1

在内部循环块中使用局部变量来记住与该迭代关联的行和列。

@for(var row = 0; row<dogList.Count; row++)
{
    <tr>
        <td style="width:120px;">@dogList[row].name</td>
        @for (var col = 0; col<dogList.Count; col++)
        {
            int currentRow = row;
            int currentCol = col;
            <td style="width:120px;">
                <input type="number" 
                    value="@dogSpeed[row][col]"
                    @oninput="@(e => {this.updateDogSpeed(currentRow, currentCol, e);})"
                />
            </td>
        }
    </tr>
}

每次循环迭代都会有一组新的这些变量,而实际的循环变量会改变它们的值。

有关详细信息,请参阅 C# 循环中捕获的变量

评论

0赞 TomEberhard 11/16/2023
工作得很好,感谢您提供有关捕获变量的链接。你真棒!