使用select2:opening事件结合Ajax首次点击下拉无数据,二次点击正常
解决Select2首次点击下拉无法加载Ajax选项的问题
我之前也碰到过一模一样的情况,问题根源在于**select2:opening事件的触发时机和Ajax异步请求的冲突**。当select2-opening事件触发时,Select2已经开始着手渲染下拉菜单了,但你的Ajax请求是异步执行的——首次点击时,下拉菜单已经显示出来,可此时Ajax还没返回数据;等数据回来手动添加完<option>后,Select2并没有感知到DOM的变化,自然不会重新渲染这些新选项。第二次点击时,选项已经存在于DOM中,所以就能正常显示了。
快速修复现有代码
你只需要在Ajax的success回调末尾,加一行代码让Select2重新识别新添加的选项即可:
$("#Select2ID").on("select2-opening", function () { var e = document.getElementById("AnotherID"); code= e.options[e.selectedIndex].value; $.ajax( { type: 'POST', dataType: 'json', url: '/Controller/Action', data: { "Code": code}, success: function (data) { selectClear("Select2ID"); var select = document.getElementById("Select2ID"); for (var item in data) { var opt = document.createElement("option"); opt.value = data[item].id; opt.innerHTML = data[item].text; select.appendChild(opt); } // 关键:通知Select2刷新选项列表 $("#Select2ID").trigger("change.select2"); }, error: function (err) { console.log(err); }, }); function selectClear(item) { var select = document.getElementById(item); while (select.firstChild) { select.removeChild(select.firstChild); } } });
更优方案:使用Select2自带的Ajax配置
其实Select2本身就内置了Ajax加载选项的功能,比手动写Ajax+事件监听更可靠,还能自动处理加载状态、请求缓存等细节。推荐改成这种方式:
$("#Select2ID").select2({ ajax: { url: '/Controller/Action', type: 'POST', dataType: 'json', delay: 250, // 输入延迟,避免频繁触发请求 data: function() { // 获取AnotherID的选中值作为请求参数 var code = $("#AnotherID").val(); return { Code: code }; }, processResults: function(data) { // 把后端返回的数据格式化为Select2需要的结构 return { results: data.map(item => ({ id: item.id, text: item.text })) }; }, cache: true // 缓存请求结果,提升重复点击的体验 }, placeholder: "请选择", allowClear: true // 可选:允许清空已选中的值 }); // 可选:当AnotherID的选中值变化时,重置Select2的选中状态 $("#AnotherID").on("change", function() { $("#Select2ID").val(null).trigger("change"); });
这种方式下,Select2会在下拉菜单打开时自动触发Ajax请求,数据返回后自动渲染选项,完全避开了手动操作DOM和事件时机的问题,代码也更简洁。
内容的提问来源于stack exchange,提问作者Mgbrain
相关产品推荐
相关产品推荐

