.Net Core Blazor-使用与<;绑定的输入复选框时发生Javascript错误;tr>;onclick

.Net Core Blazor-使用与<;绑定的输入复选框时发生Javascript错误;tr>;onclick,blazor,blazor-server-side,Blazor,Blazor Server Side,我正在为Blazor服务器端应用程序编写Blazor组件,它将显示一个数据表并允许选择一行或多行。其思想是在表的第一列中有一个复选框,在其余列中有行数据。通过单击复选框或单击行中的任意位置来选择/取消选择该行。这是通过将输入复选框绑定到row对象上的bool并在tr元素上使用onclick来实现的 <tr @onclick="() => item.Toggle()"> <td><input type="checkbox" @bind="item.Sel

我正在为Blazor服务器端应用程序编写Blazor组件,它将显示一个数据表并允许选择一行或多行。其思想是在表的第一列中有一个复选框,在其余列中有行数据。通过单击复选框或单击行中的任意位置来选择/取消选择该行。这是通过将输入复选框绑定到row对象上的bool并在tr元素上使用onclick来实现的

<tr @onclick="() => item.Toggle()">
    <td><input type="checkbox" @bind="item.Selected" /></td>
    <td>@item.Number</td>
    <td>@item.Text</td>
</tr>
如果我删除
tr
元素的
onclick
,它工作正常。由于每当单击行时,
onclick
就会触发,因此我猜与复选框上的绑定存在一些冲突。然而,我没有足够的Javascript技能来进一步研究。我可以通过为每个
td
元素(第一个复选框除外)而不是整个
tr
启动
onclick
来避免这种情况,但是当有很多列时,这会变得单调乏味,有点难看。由于blazor.js中的这一点是失败的,我想知道这是否是blazor的一个缺陷/限制


任何想法都欢迎。谢谢。

请尝试以下代码。。。注意:我做了一些改动,不是因为它们是问题的原因,等等,我只是忍不住要有自己的风格。但是,您应该关注如何绑定到元素。请注意,这样绑定到复选框的checked属性就足够了:
checked=“@row.Selected”
。 我希望你在寻找这样的解决方案

<table class="table table-hover">
    <thead>
        <tr>
            <th>Select</th>
            <th>Number</th>
            <th>Text</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var row in rows)
        {
            <tr @onclick="@(() => row.Selected = !row.Selected)">
                <td><input type="checkbox" checked="@row.Selected" /></td>
                <td>@row.Number</td>
                <td>@row.Text</td>
            </tr>
        }
    </tbody>
</table>

@code
{
   List<Row> rows = Enumerable.Range(1, 10).Select(i => new Row { Selected = 
            false, Number = i, Text = $"Item {i}" }).ToList();

  private class Row
  {
    public bool Selected { get; set; }
    public int Number { get; set; }
    public string Text { get; set; }

 }

挑选
数
正文
@foreach(行中的变量行)
{
@行,号码
@行。文本
}
@代码
{
列表行=可枚举。范围(1,10)。选择(i=>新行{Selected=
false,Number=i,Text=$“Item{i}”);
私家班排
{
已选择公共布尔值{get;set;}
公共整数{get;set;}
公共字符串文本{get;set;}
}
}

我以为我必须使用@bind,但我仍然不确定为什么不能

通常,您可以使用@bind指令在Html元素和数据源之间创建双向数据绑定。但在这种情况下,从数据源到复选框的单向数据绑定就足够了,因为tr元素上的单击操作触发的lambda表达式将切换boolean row.Selected属性。因此,组件将重新渲染,并且复选框将被选中或取消选中。取决于以前的状态

注意:编译器处理@bind指令时,如果将该指令应用于复选框,则会创建两个属性,这两个属性应等同于以下内容:

<td><input type="checkbox" checked="@row.Selected" @onchange="@((args) => row.Selected = (bool) args.Value)" /></td>

如果您使用此代码而不是上面的代码,您的应用程序仍然可以正常工作,但您现在必须已经了解,为复选框引发的更改事件是多余的

但是,你瞧,如果你使用@bind指令,让编译器代表你,你的代码就会失败。我猜这是一个未报告的错误

我真的希望我没有通过添加上面的内容使事情变得更复杂


希望这有帮助…

太好了。非常感谢。我以为我必须使用@bind,但我仍然不确定为什么不能。关于什么时候该做,什么时候不该做,你们有什么指导吗?至于风格,你们的更适合这个演示。当我的应用程序中有
selective
类时,切换方法确实更有意义。我在演示中忘记了使用
Enumerable.Range
,因为我对它几乎没有什么用处。真正的应用程序使用EF核心。再次感谢。
<table class="table table-hover">
    <thead>
        <tr>
            <th>Select</th>
            <th>Number</th>
            <th>Text</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var row in rows)
        {
            <tr @onclick="@(() => row.Selected = !row.Selected)">
                <td><input type="checkbox" checked="@row.Selected" /></td>
                <td>@row.Number</td>
                <td>@row.Text</td>
            </tr>
        }
    </tbody>
</table>

@code
{
   List<Row> rows = Enumerable.Range(1, 10).Select(i => new Row { Selected = 
            false, Number = i, Text = $"Item {i}" }).ToList();

  private class Row
  {
    public bool Selected { get; set; }
    public int Number { get; set; }
    public string Text { get; set; }

 }
<td><input type="checkbox" checked="@row.Selected" @onchange="@((args) => row.Selected = (bool) args.Value)" /></td>