You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用jQuery重载Select2多级联动下拉框数据问题排查

解决Select2父子多选下拉框更新后残留初始值的问题

我之前也碰到过类似的坑——销毁重建Select2经常会因为实例清理不彻底留下旧数据,其实咱们完全不用走销毁重建的路子,直接操作下拉框的选项并触发Select2的状态更新就稳多了。结合你的场景,给你一套完整的解决方案:

第一步:准备本地静态数据结构

先把国家对应的城市数据整理成键值对,方便快速查找:

// 本地静态城市映射,key是国家ID,value是城市数组(包含id和text字段,适配Select2)
const cityMap = {
    "cn": [
        { id: "bj", text: "北京" },
        { id: "sh", text: "上海" },
        { id: "gz", text: "广州" }
    ],
    "us": [
        { id: "ny", text: "纽约" },
        { id: "la", text: "洛杉矶" },
        { id: "chi", text: "芝加哥" }
    ],
    "jp": [
        { id: "tok", text: "东京" },
        { id: "os", text: "大阪" }
    ]
};

第二步:Razor渲染初始下拉框

确保城市下拉框初始可以是空的(或者根据需求默认不加载任何选项):

<!-- 国家多选下拉框 -->
<select id="countrySelect" multiple class="form-control select2">
    @foreach (var country in Model.Countries)
    {
        <option value="@country.Id">@country.Name</option>
    }
</select>

<!-- 城市多选下拉框,初始为空 -->
<select id="citySelect" multiple class="form-control select2"></select>

第三步:初始化Select2并处理关联逻辑

核心是监听国家选择变化,直接更新城市下拉框的选项,不需要销毁重建

$(document).ready(function() {
    // 初始化两个Select2多选组件
    $('#countrySelect').select2({
        placeholder: "请选择国家",
        width: "100%"
    });

    $('#citySelect').select2({
        placeholder: "请选择城市",
        width: "100%"
    });

    // 监听国家选择变更事件
    $('#countrySelect').on('change', function() {
        const selectedCountryIds = $(this).val() || []; // 多选可能返回数组,空选时是null,转成空数组
        const citySelect = $('#citySelect');

        // 关键1:彻底清空城市下拉框的所有旧选项(包括已选中的)
        citySelect.empty();

        // 关键2:收集所有选中国家对应的城市
        let allCities = [];
        selectedCountryIds.forEach(countryId => {
            if (cityMap[countryId]) {
                allCities = allCities.concat(cityMap[countryId]);
            }
        });

        // 关键3:添加新的城市选项到下拉框
        allCities.forEach(city => {
            // 创建Option元素,最后两个false表示默认不选中、不触发选中事件
            citySelect.append(new Option(city.text, city.id, false, false));
        });

        // 关键4:触发Select2的change事件,让新选项生效并更新组件状态
        citySelect.trigger('change');
    });

    // 可选:如果页面加载时国家有默认选中值,手动触发一次change事件加载对应城市
    $('#countrySelect').trigger('change');
});

为什么之前的销毁重建会有问题?

销毁Select2时,虽然调用了.select2('destroy'),但有时候DOM里的旧<option>元素没被彻底清除,或者Select2内部的状态缓存没清空,重建后就会残留之前的选中值或旧选项。而直接操作DOM选项+触发更新的方式,是Select2官方推荐的动态更新数据的方法,更稳定可靠。

额外注意事项

  • 如果需要支持多选国家,要记得合并所有选中国家的城市列表,避免只显示最后一个选中国家的城市
  • 初始加载时如果国家有默认选中项,一定要手动触发一次change事件,否则城市下拉框会是空的
  • 确保cityMap里的国家ID和下拉框的value值完全匹配,否则会找不到对应的城市

内容的提问来源于stack exchange,提问作者TheFallenOne

火山引擎 最新活动