.NET Core局部视图中Modal的JavaScript在Ajax Post后失效如何解决?
解决Ajax返回后Autocomplete功能失效的问题
我完全懂你遇到的糟心事——第一次打开Modal时Autocomplete好好的,结果Ajax提交(比如表单验证失败返回新的Modal内容)之后,这个功能直接罢工了。核心原因其实很直白:你第一次加载局部视图时,JS代码只给当时存在的#BossName元素绑定了Autocomplete逻辑,但Ajax返回新的DOM内容后,新生成的#BossName元素根本没被重新初始化。
下面是具体的修正方案,一步步来就能搞定:
步骤1:把Autocomplete初始化逻辑封装成可复用函数
把局部视图里的Autocomplete代码抽成独立函数,这样每次更新Modal内容后都能重新调用它,避免重复写代码:
function initBossAutocomplete() { // 先移除旧的绑定,防止重复触发事件 $('#BossName').autoComplete('destroy').autoComplete({ resolver: 'custom', minLength: 2, formatResult: function (item) { return { value: item.value, text: "[" + item.value + "] " + item.text, } }, noResultsText:'无匹配数据,请确认公司字段是否有数据', events: { search: function (qry, callback) { // 这里建议把ActionUrl提前渲染到全局变量,避免局部视图路径问题 $.ajax('@Url.Action("GetRolesByAutoComplete","Roles")', { data: { 'q': qry, 'key': document.getElementById('CompanyCode').value } }).done(function (res) { callback(res) }); } } }); // 同样先移除旧事件再绑定新的 $('#BossName').off('autocomplete.select').on('autocomplete.select', function (evt, item) { console.log(item); $('#BossID').val(item.value); $('#BossName').val(item.text); }); }
这里两个关键细节:
- 初始化前调用
autoComplete('destroy'),彻底清除旧的插件实例,避免冲突 - 绑定
autocomplete.select事件前用off移除旧绑定,防止同一事件被多次触发
步骤2:在合适的时机调用初始化函数
1. 第一次加载Modal时自动初始化
在局部视图的JS代码末尾,添加函数调用,确保第一次打开Modal时Autocomplete生效:
// 局部视图的JS部分 @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} <script src="~/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.min.js"></script> <script> // 上面的initBossAutocomplete函数... // 第一次加载Modal时初始化 initBossAutocomplete(); </script>
2. Ajax返回新内容后重新初始化
修改主视图里的Ajax成功回调,当验证失败替换Modal内容后,立刻调用初始化函数:
success: function (redata) { console.log(redata); if (redata.status === "success") { PlaceHolderElement.find('.modal').modal('hide'); } else { var newBody = $('.modal-body', redata); var newFoot = $('.modal-footer', redata); PlaceHolderElement.find('.modal-body').replaceWith(newBody); PlaceHolderElement.find('.modal-footer').replaceWith(newFoot); // 核心:替换DOM后重新初始化Autocomplete initBossAutocomplete(); } },
额外优化小技巧
为了避免局部视图里的Url路径问题,可以把Action地址提前渲染到主视图的全局变量里:
<!-- 主视图里添加 --> <script> window.RolesAutocompleteUrl = '@Url.Action("GetRolesByAutoComplete","Roles")'; </script>
然后在initBossAutocomplete函数里用window.RolesAutocompleteUrl代替硬编码的Url,这样更稳妥。
这样修改后,不管是第一次打开Modal,还是Ajax返回新的表单内容,Autocomplete都会被正确初始化,功能就能正常工作了。
内容的提问来源于stack exchange,提问作者Miles
相关产品推荐
相关产品推荐

