如何使用Knockout从复杂对象取值生成国家地区两级下拉选择框
实现方案
前置说明
你提供的原始optionsList数据有两处小问题需要先修正:
- 外层用了
observableArray但实际里面只包了1个国家字典对象,结构需要调整为可直接读取的国家集合 - 西班牙ES的regions配置中,
24项结尾缺少逗号,会报语法错误
核心实现思路
- 先把原始的国家字典结构转成下拉框可用的数组格式,每个元素包含国家代码、国家名称、regions属性
- 定义可观察变量存储当前选中的国家
- 用计算属性动态返回选中国家对应的地区列表,如果国家没有regions属性就返回空数组
- 下拉框通过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
相关产品推荐
相关产品推荐

