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

如何正确处理JavaScript移除Blazor渲染元素的问题?

Blazor中JS修改DOM引发的组件同步问题及解决方案

问题背景

在Blazor框架中,通过JavaScript直接修改DOM并非最佳实践,但当前场景下找不到替代方案:我使用Blazor的for循环遍历数组渲染了一组Material Web的<MdInputChip>自定义组件,用户点击芯片的X按钮可移除芯片。但点击X时,Web Component的内部代码会自行将元素从DOM中移除,这部分逻辑无法修改。

可复现代码

<div @key="@DateTime.UtcNow.ToString()">
    @for (int i = 0; i < values.Count; i++)
    {
        var z = i;
        var item = values[z];

        <p @key="@(DateTime.UtcNow.ToString() + z)" @onchange="(() => Remove(z))">
            @(item)
            <button onclick="this.parentElement.dispatchEvent(new Event('change')); this.parentElement.remove();">
                Remove
            </button>
        </p>
    }
</div>

@code {
    List<string> values = new() { "A", "B", "C" };

    void Remove(int index)
    {
        values.RemoveAt(index);
        Console.WriteLine(string.Join(",", values));
    }
}

核心问题

点击移除中间元素(比如B)时,多数情况下末尾元素(C)也会被错误移除。尝试通过@key属性解决:

  • 给<p>元素添加@key:数组后续修改时会触发多种异常
  • 给外层<div>添加@key并移除<p>的@key:仅降低问题出现频率,仍偶发异常

由于场景对性能要求不高,重新渲染整个区域完全可行,希望找到可靠的解决办法,包括让Blazor直接销毁区域后重新渲染所有内容的方案。

针对该场景的可行方案

幸运的是,当前场景中可通过preventDefault()取消Web Component的自动移除事件,具体实现如下:

export function beforeStart() {
    document.addEventListener("remove", e => {
        if (e.target?.tagName === "MD-INPUT-CHIP") {
            e.preventDefault();
        }        
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:17:50