You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net Core Blazor中<tr>点击与复选框绑定引发JS错误的求助

Fix for Blazor Server Row Click and Checkbox Binding Conflict

我之前在Blazor Server项目里也碰到过一模一样的问题,这个错误其实是事件冒泡引发的双重状态更新冲突导致的,下面给你说说怎么解决,以及背后的原因:

问题根源

当你点击复选框时,浏览器的点击事件会默认向上冒泡到父级的<tr>元素,触发@onclick="() => item.Toggle()"方法。这就相当于同时触发了两次item.Selected的状态变更:

  1. 复选框的双向绑定自动更新item.Selected
  2. 行的点击事件调用Toggle()再次反转item.Selected

这种重复且冲突的状态修改会让Blazor的渲染引擎在同步DOM时出现异常,最终抛出你看到的Cannot read property 'parentNode' of undefined错误。

最简单的解决方法:阻止复选框的事件冒泡

只需要给复选框添加@onclick:stopPropagation="true"属性,就能阻止点击事件冒泡到父级的<tr>。这样:

  • 点击复选框时,只会触发双向绑定的状态更新,不会触发行的点击事件
  • 点击行的其他区域时,依然会触发Toggle()方法切换选中状态,复选框也会自动同步勾选状态

修改后的复选框代码:

<td><input type="checkbox" @bind="item.Selected" @onclick:stopPropagation="true" /></td>

完整的修改后组件代码

@page "/test"
@if (data == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table table-hover">
        <thead>
            <tr>
                <th>Select</th>
                <th>Number</th>
                <th>Text</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in data)
            {
                <tr @onclick="() => item.Toggle()">
                    <td><input type="checkbox" @bind="item.Selected" @onclick:stopPropagation="true" /></td>
                    <td>@item.Number</td>
                    <td>@item.Text</td>
                </tr>
            }
        </tbody>
    </table>
}
@code {
    private List<Row> data;

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

        public Row(int number)
        {
            Selected = false;
            Number = number;
            Text = $"Item {number}";
        }

        public void Toggle() => Selected = !Selected;
    }

    protected override void OnInitialized()
    {
        data = new List<Row>
        {
            new Row(1),
            new Row(2),
            new Row(3)
        };
    }
}

额外说明

这个方法既保留了你想要的“点击行任意位置或复选框均可切换选中状态”的功能,又不用给每个<td>单独添加点击事件,完美解决了代码繁琐的问题。本质上是避免了Blazor渲染时的状态冲突,让DOM更新流程保持一致。

内容的提问来源于stack exchange,提问作者macandpcdoctors

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:32:52