.Net Core Blazor中<tr>点击与复选框绑定引发JS错误的求助
Fix for Blazor Server Row Click and Checkbox Binding Conflict
我之前在Blazor Server项目里也碰到过一模一样的问题,这个错误其实是事件冒泡引发的双重状态更新冲突导致的,下面给你说说怎么解决,以及背后的原因:
问题根源
当你点击复选框时,浏览器的点击事件会默认向上冒泡到父级的<tr>元素,触发@onclick="() => item.Toggle()"方法。这就相当于同时触发了两次item.Selected的状态变更:
- 复选框的双向绑定自动更新
item.Selected - 行的点击事件调用
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
相关产品推荐
相关产品推荐

