You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Knockout从复杂对象取值生成国家地区两级下拉选择框

实现方案

前置说明

你提供的原始optionsList数据有两处小问题需要先修正:

  • 外层用了observableArray但实际里面只包了1个国家字典对象,结构需要调整为可直接读取的国家集合
  • 西班牙ES的regions配置中,24项结尾缺少逗号,会报语法错误

核心实现思路

  1. 先把原始的国家字典结构转成下拉框可用的数组格式,每个元素包含国家代码、国家名称、regions属性
  2. 定义可观察变量存储当前选中的国家
  3. 用计算属性动态返回选中国家对应的地区列表,如果国家没有regions属性就返回空数组
  4. 下拉框通过Knockout的options绑定实现渲染,地区下拉框可以用visible绑定控制是否显示

完整代码实现

JS部分(ViewModel定义)

// 先修正并处理原始数据
const rawCountryData = {
    'AD':{'name':'Andora'},
    'AE':{'name':"United Arab Emirates"},
    'AG':{'name':"Antigua & Barbuda"},
    'ES':{'name':"Spain", 'regions':{
            "22": {
                "code": "A Coruсa",
                "name": "A Coruña"
            },
            "23": {
                "code": "Alava",
                "name": "Alava"
            },
            "24": {
                "code": "Albacete",
                "name": "Albacete"
            },
            "25": {
                "code": "Zaragoza",
                "name": "Zaragoza"
            }
        }},
    'AT':{'name':"Austria", 'regions':{
            "95": {
                "code": "WI",
                "name": "Wien"
            },
            "96": {
                "code": "NO",
                "name": "Niederösterreich"
            }
        }},
    'AU':{'name':"Australia", 'regions':{
            "569": {
                "code": "ACT",
                "name": "Australian Capital Territory"
            },
            "570": {
                "code": "NSW",
                "name": "New South Wales"
            },
            "571": {
                "code": "VIC",
                "name": "Victoria"
            },
            "572": {
                "code": "QLD",
                "name": "Queensland"
            }
        }}
};

function AppViewModel() {
    const self = this;
    // 转成国家数组,每个元素带code、name、regions属性
    self.countryOptions = ko.computed(function() {
        return Object.keys(rawCountryData).map(countryCode => {
            return {
                code: countryCode,
                name: rawCountryData[countryCode].name,
                regions: rawCountryData[countryCode].regions || null
            }
        });
    });
    
    // 存储当前选中的国家
    self.selectedCountry = ko.observable();
    
    // 动态返回选中国家对应的地区数组
    self.regionOptions = ko.computed(function() {
        const selected = self.selectedCountry();
        if (!selected || !selected.regions) {
            return [];
        }
        // 把地区字典转成数组
        return Object.keys(selected.regions).map(regionId => {
            return {
                id: regionId,
                code: selected.regions[regionId].code,
                name: selected.regions[regionId].name
            }
        });
    });
    
    // 存储选中的地区
    self.selectedRegion = ko.observable();
}

// 绑定Knockout
ko.applyBindings(new AppViewModel());

HTML部分(下拉框绑定)

<!-- 国家下拉框 -->
<div>
    <label>选择国家:</label>
    <select 
        data-bind="
            options: countryOptions,
            optionsText: 'name',
            optionsValue: 'code',
            value: selectedCountry,
            optionsCaption: '请选择国家'
        "
    ></select>
</div>

<!-- 地区下拉框,只有有地区选项时显示 -->
<div data-bind="visible: regionOptions().length > 0">
    <label>选择地区:</label>
    <select 
        data-bind="
            options: regionOptions,
            optionsText: 'name',
            optionsValue: 'id',
            value: selectedRegion,
            optionsCaption: '请选择地区'
        "
    ></select>
</div>

逻辑说明

  • 国家下拉框会自动加载所有国家选项,选中国家后会自动触发regionOptions的重新计算
  • 如果选中的国家没有regions属性,地区下拉框会自动隐藏
  • 所有选中值都通过selectedCountry和selectedRegion两个可观察变量实时获取,可直接用于后续业务逻辑

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:45:04