Blazor模态框多次使用时Render Fragment不刷新问题
Blazor模态框多次引用时内容不刷新的解决方案
问题根源
- 静态ID冲突:组件内
ElementIds是静态类,其Modal和ModalClose的Guid为静态属性,所有Modal实例会共享同一组ID,导致DOM中多个dialog元素id重复。JS通过getElementById查找时只会返回第一个匹配元素,因此后续模态框始终显示第一个的内容。 - 引用变量复用:页面中两个Modal绑定到同一个
_modalRef变量,最终只有最后一个Modal实例被赋值,点击按钮时实际操作的是最后一个实例,但ID冲突导致显示第一个的内容。
修复步骤
1. 修改Modal组件,使用实例级唯一ID
将静态ID改为实例属性,确保每个Modal组件拥有独立的DOM元素ID:
@inject IJSRuntime JsRuntime <dialog id="@ModalId" class="modal"> <div class="modal-box w-11/12 max-w-2xl"> <div class="modal-action" style="margin: 10px"> <form id="@ModalCloseId" method="dialog"> <button class="btn btn-circle"> <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24" id="Close"> <path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M15.7,14.3c0.4,0.4,0.4,1,0,1.4c-0.4,0.4-1,0.4-1.4,0 L12,13.4l-2.3,2.3c-0.4,0.4-1,0.4-1.4,0c-0.4-0.4-0.4-1,0-1.4l2.3-2.3L8.3,9.7c-0.4-0.4-0.4-1,0-1.4c0.4-0.4,1-0.4,1.4,0l2.3,2.3 l2.3-2.3c0.4-0.4,1-0.4,1.4,0c0.4,0.4,0.4,1,0,1.4L13.4,12L15.7,14.3z" fill="#717af7" class="color000000 svgShape"></path> </svg> </button> </form> </div> <div class="h-full px-3 pb-4 overflow-y-auto "> @Content </div> </div> </dialog> @code { [Parameter] public RenderFragment? Content { get; set; } // 每个实例生成唯一ID private string ModalId { get; } = Guid.NewGuid().ToString(); private string ModalCloseId { get; } = Guid.NewGuid().ToString(); public void ShowModal() { _ = JsRuntime.InvokeVoidAsync("eval", $"document.getElementById('{ModalId}').showModal()"); } public void CloseModal() { _ = JsRuntime.InvokeVoidAsync("eval", $"document.getElementById('{ModalCloseId}').submit()"); } }
2. 修改页面使用代码,为每个Modal创建独立引用
每个Modal需要绑定到不同的引用变量,确保点击按钮时操作对应实例:
<button @onclick="()=>_modalRef1.ShowModal()" class="btn avatar" style="position: absolute;bottom: 40px;right: 40px; background: red">打开第一个模态框</button> <Modal @ref="@_modalRef1"> <Content> <h1>hello</h1> </Content> </Modal> <button @onclick="()=>_modalRef2.ShowModal()" class="btn avatar" style="position: absolute;bottom: 0;right: 40px; background: red">打开第二个模态框</button> <Modal @ref="@_modalRef2"> <Content> <h1>hello message 1</h1> </Content> </Modal> @code{ private Modal _modalRef1; private Modal _modalRef2; }
3. (可选)优化JS调用方式,避免使用eval
使用Blazor的ElementReference替代ID查找,更安全且彻底规避ID冲突:
修改Modal组件
@inject IJSRuntime JsRuntime <dialog @ref="_modalElement" class="modal"> <div class="modal-box w-11/12 max-w-2xl"> <div class="modal-action" style="margin: 10px"> <form @ref="_closeFormElement" method="dialog"> <button class="btn btn-circle"> <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24" id="Close"> <path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M15.7,14.3c0.4,0.4,0.4,1,0,1.4c-0.4,0.4-1,0.4-1.4,0 L12,13.4l-2.3,2.3c-0.4,0.4-1,0.4-1.4,0c-0.4-0.4-0.4-1,0-1.4l2.3-2.3L8.3,9.7c-0.4-0.4-0.4-1,0-1.4c0.4-0.4,1-0.4,1.4,0l2.3,2.3 l2.3-2.3c0.4-0.4,1-0.4,1.4,0c0.4,0.4,0.4,1,0,1.4L13.4,12L15.7,14.3z" fill="#717af7" class="color000000 svgShape"></path> </svg> </button> </form> </div> <div class="h-full px-3 pb-4 overflow-y-auto "> @Content </div> </div> </dialog> @code { [Parameter] public RenderFragment? Content { get; set; } private ElementReference _modalElement; private ElementReference _closeFormElement; public async Task ShowModal() { await JsRuntime.InvokeVoidAsync("showModal", _modalElement); } public async Task CloseModal() { await JsRuntime.InvokeVoidAsync("submitForm", _closeFormElement); } }
在wwwroot/js/site.js中添加JS函数
function showModal(element) { element.showModal(); } function submitForm(formElement) { formElement.submit(); }
内容的提问来源于stack exchange,提问作者Regestea
相关产品推荐
相关产品推荐

