Blazor循环内@onclick事件实现单条alert消息关闭的问题
问题根因
- 你当前所有告警共用了全局的
value变量控制类名,只要变量修改所有绑定该变量的元素都会同步变更样式,因此会全部关闭 - 循环内写死了固定id
alertmessage,自然会生成重复id,不符合HTML规范也无法用id唯一标识元素
推荐实现方案(Blazor数据驱动思路,无需手动操作DOM)
Blazor是数据驱动渲染的框架,不需要像原生JS那样通过id定位DOM修改显隐,直接通过数据状态控制渲染即可,有两种实现方式可选:
方案1:可修改Alert实体类的场景
给你的Alert模型新增IsHidden布尔属性,默认值为false,直接用该属性控制单条告警的显隐:
@if(alerts?.Any() == true) { @foreach(var alert in alerts.Where(a => a.type == "alert" && a.valid == true)) { <!-- 动态拼接id避免重复,加@key优化Blazor重绘性能 --> <div id="alert_@alert.id" class="@(alert.IsHidden ? "hidden" : "show")" @key="alert.id"> <!-- 点击时传入当前alert对象,修改它的IsHidden状态 --> <button type="button" @onclick="() => HideAlert(alert)">Hide this element</button> </div> } } @code { // 你的Alert实体类新增IsHidden属性即可 // public class Alert { public int id {get;set;} public string type {get;set;} public bool valid {get;set;} public bool IsHidden {get;set;} = false; } private List<Alert> alerts = new(); private void HideAlert(Alert targetAlert) { targetAlert.IsHidden = true; } }
方案2:不能修改Alert实体类的场景
如果无法修改Alert模型的定义,可以额外定义一个集合存储已关闭的告警id,通过判断当前告警id是否在关闭集合内控制显隐:
@if(alerts?.Any() == true) { @foreach(var alert in alerts.Where(a => a.type == "alert" && a.valid == true)) { <div id="alert_@alert.id" class="@(_closedAlertIds.Contains(alert.id) ? "hidden" : "show")" @key="alert.id"> <button type="button" @onclick="() => HideAlert(alert.id)">Hide this element</button> </div> } } @code { private List<Alert> alerts = new(); // 存储已经关闭的告警id private readonly HashSet<int> _closedAlertIds = new(); private void HideAlert(int alertId) { _closedAlertIds.Add(alertId); } }
额外优化建议
- 每次轮询拿到新的告警列表时,如果是方案2可以先清空
_closedAlertIds,避免之前关闭的id和新告警id重复导致异常隐藏 - 不需要手动通过JS操作DOM修改显隐,Blazor会自动根据数据状态更新DOM,性能和可维护性都更好
内容的提问来源于stack exchange,提问作者Kembo
相关产品推荐
相关产品推荐

