JavaScript:多对象JSON数组选中区域的数组长度读取异常
解决下拉框联动中获取区域对应城市数组长度返回undefined的问题
问题根源
你的myObj是一个数组,数组里的每个元素都是单个键值对的对象(键是区域名称,值是城市数组)。当你用myObj[region]拿到的是这个对象,不是城市数组——对象本身没有.length属性,所以调用allCities.length会返回undefined,但直接打印allCities会显示这个包含数组的对象。
修正方案
1. 正确获取城市数组
在fillCities函数里,拿到区域对象后,提取出里面的城市数组:
var allCitiesObj = myObj[region]; var allCities = Object.values(allCitiesObj)[0]; // 提取对象里的数组
因为每个区域对象只有一个键值对,所以Object.values取第一个元素就是我们要的城市数组,此时allCities.length就能正常获取长度了。
2. 修复城市下拉框的选项内容
原来的代码直接把city对象塞到option里,会显示[object Object],应该用city.cityName作为显示文本和value:
cities.innerHTML += "<option value=\"" + city.cityName + "\">" + city.cityName + "</option>";
3. (可选)优化区域下拉框的初始化逻辑
可以把区域名称直接作为option的value,这样后续获取更直观,不用依赖索引:
Object.keys(myObj).forEach(function(key) { var regionName = Object.getOwnPropertyNames(myObj[key])[0]; regions.innerHTML += "<option value=\"" + regionName + "\">" + regionName + "</option>"; });
对应的fillCities函数里,需要遍历myObj找到匹配区域名称的对象:
function fillCities(val) { var cities = document.getElementById("m_cities"); cities.innerHTML = " <option value='0'>اختر مدينة التوصيل</option>"; // 找到匹配区域名称的对象 var regionObj = myObj.find(item => Object.keys(item)[0] === val); var allCities = Object.values(regionObj)[0]; console.log(allCities.length); for (var i = 0; i < allCities.length; i++) { var city = allCities[i]; cities.innerHTML += "<option value=\"" + city.cityName + "\">" + city.cityName + "</option>"; } }
修改后的完整代码
JavaScript代码
const myJSON = '[' + '{"المنطقة الشرقية":[' + '{ "cityName":"الدمام","deliveryTime":"1" },' + '{ "cityName":"الخبر","deliveryTime":"1" },' + '{ "cityName":"القطيف","deliveryTime":"1" },' + '{ "cityName":"صفوى","deliveryTime":"1" },' + '{ "cityName":"سيهات","deliveryTime":"1" },' + '{ "cityName":"عنك","deliveryTime":"1" },' + '{ "cityName":"الظهران","deliveryTime":"1" },' + '{ "cityName":"الجبيل","deliveryTime":"1" },' + '{ "cityName":"الهفوف","deliveryTime":"1" },' + '{ "cityName":"رأس تنورة","deliveryTime":"1" },' + '{ "cityName":"بقيق","deliveryTime":"1" },' + '{ "cityName":"المبرز","deliveryTime":"1" },' + '{ "cityName":"رحيمة","deliveryTime":"1" },' + '{ "cityName":"الأحساء","deliveryTime":"1" },' + '{ "cityName":"الخفجي","deliveryTime":"1" },' + '{ "cityName":"النعيرية","deliveryTime":"1" },' + '{ "cityName":"تاروت","deliveryTime":"1" }' + ']},' + '{"المنطقة الوسطى":[' + '{ "cityName":"الرياض","deliveryTime":"" },' + '{ "cityName":"الخرج","deliveryTime":"" },' + '{ "cityName":"بريدة","deliveryTime":"" },' + '{ "cityName":"عنيزة","deliveryTime":"" },' + '{ "cityName":"الرس","deliveryTime":"" },' + '{ "cityName":"المجمعة","deliveryTime":"" }' + ']}' + ']'; const myObj = JSON.parse(myJSON); var regions = document.getElementById("m_continent"); regions.innerHTML = " <option value='-1'>اختر منطقة التوصيل</option>"; // 初始化区域下拉框(优化后用区域名称作为value) Object.keys(myObj).forEach(function(key) { var regionName = Object.getOwnPropertyNames(myObj[key])[0]; regions.innerHTML += "<option value=\"" + regionName + "\">" + regionName + "</option>"; }); function fillCities(val) { if (val === "-1") return; var cities = document.getElementById("m_cities"); cities.innerHTML = " <option value='0'>اختر مدينة التوصيل</option>"; // 找到选中区域对应的对象 var regionObj = myObj.find(item => Object.keys(item)[0] === val); var allCities = Object.values(regionObj)[0]; console.log("城市数组长度:", allCities.length); // 现在能正常获取长度 for (var i = 0; i < allCities.length; i++) { var city = allCities[i]; cities.innerHTML += "<option value=\"" + city.cityName + "\">" + city.cityName + "</option>"; } }
HTML代码
<!DOCTYPE html> <html> <body style="direction:rtl"> <h2>مدن وأوقات التوصيل</h2> <p>يمكنك تقدير وقت وصول طلبك لمدينتك</p> <label for="m_continent">اختر منطقتك</label> <select id="m_continent" onchange="fillCities(this.value)"> </select> <br> <label for="m_cities">اختر مدينتك</label> <select id="m_cities"> <option value="0">اختر المنطقة أولا</option> </select> <p id="delivery-time"></p> </body> </html>
内容的提问来源于stack exchange,提问作者Sabbah
相关产品推荐
相关产品推荐

