适配脚本实现关闭当前Modal并加载新Modal(基于PartialViews)
问题需求
需要适配现有脚本,实现点击按钮时关闭当前模态框并加载新模态框,同时基于可复用模态框框架加载PartialViews。目前初始模态框能正常展示,但模态框内的Edit按钮会把新视图加载成新页面而非模态框。
触发模态框使用的ActionLink:
@Html.ActionLink("Select", "Details", new { id = item.id }, new { @class = "btn btn-primary", @data_modal = "" })
现有脚本
$(function () { $.ajaxSetup({ cache: false }); $("a[data-modal]").on("click", function (e) { $('#myModalContent').load(this.href, function () { $('#myModal').modal({ keyboard: true }, 'show'); bindForm(this); }); return false; }); }); function bindForm(dialog) { $('form', dialog).submit(function () { $.ajax({ url: this.action, type: this.method, data: $(this).serialize(), success: function (result) { if (result.success) { $('#myModal').modal('hide'); window.location.href = "/home/Index"; } else { $('#myModalContent').html(result); bindForm(); } } }); return false; }); }
问题根源
模态框内的Edit按钮是动态加载的PartialView内容,现有事件绑定是静态绑定,只对页面初始存在的a[data-modal]元素生效,动态生成的按钮不会触发模态框逻辑,直接跳转页面。
解决方案
1. 修改事件绑定为委托模式
把静态绑定改成基于父元素的委托,确保动态生成的a[data-modal]按钮也能触发模态框逻辑,同时在加载新内容前先关闭当前模态框。
2. 统一复用单一模态框结构
不需要多个模态框,用同一个模态框容器切换内容即可,同时处理模态框的显示/隐藏逻辑。
修改后的完整代码
模态框HTML结构(页面中只需要一个)
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="myModalLabel">Modal Title</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div id="myModalContent" class="modal-body"> <!-- PartialView内容会加载到这里 --> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> </div> </div> </div> </div>
修改后的JavaScript脚本
$(function () { $.ajaxSetup({ cache: false }); // 使用委托绑定事件,支持动态生成的元素 $(document).on("click", "a[data-modal]", function (e) { e.preventDefault(); var targetUrl = this.href; // 先关闭当前模态框 $('#myModal').modal('hide'); // 模态框关闭后加载新内容并重新显示 $('#myModal').on('hidden.bs.modal', function loadNewContent() { $('#myModalContent').load(targetUrl, function () { $('#myModal').modal({ keyboard: true }, 'show'); bindForm(this); }); // 解绑该事件,避免重复触发 $('#myModal').off('hidden.bs.modal', loadNewContent); }); }); }); function bindForm(dialog) { $('form', dialog).submit(function (e) { e.preventDefault(); $.ajax({ url: this.action, type: this.method, data: $(this).serialize(), success: function (result) { if (result.success) { $('#myModal').modal('hide'); window.location.href = "/home/Index"; } else { // 加载验证失败后的PartialView $('#myModalContent').html(result); bindForm($('#myModalContent')); } } }); }); }
关键修改点说明
- 事件委托:用
$(document).on("click", "a[data-modal]", ...)代替直接绑定,确保动态生成的按钮能触发事件。 - 模态框切换逻辑:点击新按钮时先关闭当前模态框,在
hidden.bs.modal事件触发后再加载新内容并重新显示,避免模态框叠加问题。 - 解绑重复事件:加载新内容后解绑
hidden.bs.modal的临时事件,防止多次点击时重复执行加载逻辑。 - bindForm优化:调用bindForm时传入明确的dialog参数,避免上下文丢失。
PartialView中的Edit按钮写法
确保PartialView里的Edit按钮同样使用data-modal属性,格式和初始按钮一致:
@Html.ActionLink("Edit", "Edit", new { id = Model.Id }, new { @class = "btn btn-primary", @data_modal = "" })
内容的提问来源于stack exchange,提问作者Wondering
相关产品推荐
相关产品推荐

