Select2联动切换数据集异常:徽章更新但选项未变更
解决Select2切换数据源时选项不更新的问题
你遇到的核心问题是重复初始化Select2实例导致DOM与内部状态不一致——每次切换#fam的值时,你都重新调用select2()初始化#products,这会在同一个DOM元素上叠加多个Select2实例,最终出现徽章(由模板渲染)更新了,但下拉菜单选项仍绑定旧实例数据源的异常。
修复方案:单次初始化Select2,动态更新数据源
正确的思路是先一次性完成#products的Select2初始化,保留通用配置(主题、宽度、模板函数等),后续仅在切换事件中更新数据源,而非重复初始化。
修改后的完整代码:
// 格式化文本的函数保持不变 function formatText(icon) { if (icon.badge == undefined) { return $('<span>' + icon.text + '</span>'); } else { return $('<span><span class="badge">' + icon.badge + '</span> ' + icon.text + '</span>'); } } // 一次性初始化#products的Select2实例,复用通用配置 $('#products').select2({ width: "100%", theme: 'bootstrap4', placeholder: "Select item", allowClear: true, templateSelection: formatText, templateResult: formatText }); // 初始化#fam并绑定切换事件 $('#fam').select2().on('change', function() { const selectedKey = $(this).val(); if (!selectedKey) { // 未选中值时清空产品下拉框 $('#products').val(null).trigger('change'); return; } // 注意:eval存在安全风险,建议用对象映射替代(下文会说明) const newProductData = eval(selectedKey); // 清空选中值、更新数据源并刷新Select2状态 $('#products').val(null) .select2({ data: newProductData }) .trigger('change'); });
关键优化点说明:
避免重复初始化
仅在页面加载时初始化一次#products的Select2实例,后续通过select2({ data: newData })更新数据源,确保始终只有一个实例,DOM与内部状态完全同步。替换不安全的
eval()eval()会执行任意字符串代码,存在代码注入风险,建议用对象映射管理预定义数据集:// 用键值对映射所有产品数据集 const productDataMap = { data1: [{ id: 1, text: "Product A", badge: 2 }, ...], data2: [{ id: 3, text: "Product B", badge: 3 }, ...] // 其他数据集... }; // 在切换事件中直接通过键获取数据 const newProductData = productDataMap[selectedKey];强制同步状态
更新数据后调用trigger('change'),确保Select2的选中状态和显示内容同步刷新。
这样修改后,切换#fam的值时,#products的下拉选项和徽章就能正确同步更新了。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

