【问题标题】:How to resolve problem with chain select Uncaught TypeError: Cannot read property 'forEach' of undefined如何解决链选择问题 Uncaught TypeError: Cannot read property 'forEach' of undefined
【发布时间】:2021-02-17 23:27:28
【问题描述】:

你们能帮我解决这个问题吗?我正在尝试编写一个带有 2 级链选择的脚本,但我遇到了这样的错误:

scripts.js:76 Uncaught TypeError: Cannot read property 'forEach' of 未定义

你有什么想法吗?错误显示在 console.log 最后 fucntion 和看起来像这样

未捕获的类型错误:无法读取未定义的属性“forEach” 在 cmo (scripts.js:76) 在 setTown (scripts.js:66) at scripts.js:61 cmo@scripts.js:76 setTown@scripts.js:66(匿名)@scripts.js:61

这是我的代码

var json = {
"region":{
        "Warmińsko - mazurskie":{
            "town":{
            "Olsztyn":["Mercury", "Novotel","Sheraton", "Radisson", "Gołębiewski"],
            "Elbląg": ["Mercury", "Novotel","Sheraton", "Radisson Blue", "Gołębiewski"],
            "Iława":["Mer", "Novotel","Sheraton", "Radisson", "Gołębiewski"],
            "Ostróda":["Mercury", "Novotel","Mariot", "Radisson", "Gołębiewski"],
            "Giżycko":["Mercury", "Novotel","Sheraton", "Vienna House", "Gołębiewski"],
            }
        },
        "Małopolskie":{
            "town":{
            "Kraków":["Kossak", "Novotel","Sheraton", "Radisson", "Stary"],
            "Tarnów":["Mercury", "Novotel","Sheraton", "Tarnovia", "Ibis"],
            "Oświęcim":["Mercure", "Golden Tulip","Sheraton", "Radisson", "Hampton"],
            "Skała":["Focus", "Novotel","Sheraton", "Radisson", "Zamek"],
            "Wieliczka":["Mercurius", "Novotel","Sheraton", "Arche", "Blue Star"],
        }
    },
    "Podlaskie":{
        "town":{
            "Białystok":["Altus", "Deo","Sheraton", "Radisson Blu", "Aquarion"],
            "Suwałki":["Merr", "Novotel","Ibis", "Radisson Red", "Arche"],
            "Łomża":["Mercury 2", "Telios","Sheraton", "Blue", "DeSilva"],
            "Augustów":["Mariot", "Unicus","Hampton", "Ibis Budget", "Ibis Styles"],
            "Zambrów":["Golden", "Blue Star","Sheraton", "Osteria", "Rafles"],
        }
    },
       "Podkarpackie":{
        "town":{
            "Rzeszów":["Blue Star", "Notel","Radius", "Puławski", "Grębiewski"],
            "Jasło":["Mercury2", "Novotel2","Sheraton2", "Radisson2", "Gołębiewski2"],
            "Krosno":["Mercury3", "Novotel3","Sheraton3", "Radisson3", "Gołębiewski3"],
            "Ustrzyki Górne":["Mercury4", "Novotel4","Sheraton4", "Radisson4", "Gołębiewski"],
            "Sanok":["Mercury5", "Novotel5","Sheraton5", "Radisson5", "Gołębiewski5"],
        }
    },
       "Mazowieckie":{
        "town":{
            "Warszawa":["Mercury6", "Novotel6","Sheraton6", "Radisson6", "Gołębiewski6"],
            "Sochaczew":["Mercury7", "Novotel7","Sheraton7", "Radisson7", "Gołębiewski7"],
            "Płock":["Mercury8", "Novotel8","Sheraton8", "Radisson8", "Gołębiewski8"],
            "Radom":["Mercury9", "Novotel9","Sheraton9", "Radisson9", "Gołębiewski9"],
            "Ciechanów":["Mercury0", "Novotel0","Sheraton0", "Radisson0", "Gołębiewski0"],
        }
    }
    }
}

var jsonData = JSON.parse(JSON.stringify(json));

console.log(typeof jsonData);

 var region = document.getElementById("region");
 var town = document.getElementById("town");
 var hotel = document.getElementById("hotel");

let reg = Object.keys(jsonData);
cmo(reg, region);
setTown();

function setTown(){
    town.innerHTML = "";
    let towns = jsonData[region.value];
    cmo(towns, town);
    setHotel();
};

function setHotel(){
    hotel.innerHTML = "";
    let hotels = jsonData[region.value][town.value];
    cmo(hotels, hotel);
};
function cmo(arr, s){
    arr.forEach(o => {
        let opt = document.createElement("option");
        opt.value = o;
        opt.innerHTML = o;
        s.add(opt);

    });
}
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="./styles.css">
    <title>Generowanie - wybór danych</title>
</head>
<body>

<p><label for = "region">Choose a region:</label>
<select name = "region" id = "region" onchange="setTown();">
    <option disabled selected value="">Select a region</option>
    <option value = "Warmińsko - mazurskie">Warmińsko - mazurskie</option>
    <option value = "Małopolskie">Małopolskie</option>
    <option value = "Podlaskie">Podlaskie</option>
    <option value = "Podkarpackie">Podkarpackie</option>
    <option value = "Mazowieckie">Mazowieckie</option>
</select>
</p>

<p>
<label  for = "town">Choose a town:</label>
<select name = "town" id="town" onchange="setHotel();">
</select>
</p>

<p>
<label for="hotel" id="hotel">Choose a hotel:</label>
<select name="hotel" id="hotel">
</select>
</p>

<script type="text/javascript" src="./scripts.js"></script>

</body>
</html>

【问题讨论】:

    标签: javascript


    【解决方案1】:

    我将从这个开始,即使它与你的问题无关:

    var jsonData = JSON.parse(JSON.stringify(json));

    这是不必要的。您的变量 json 是一个对象,而不是实际的 JSON。此行将其转换为 JSON(使用 stringify),然后转换回与您开始使用的对象相同的对象(使用 parse)。您可以跳过所有这些,直接使用json(最好使用一个不易误导的名称。)

    现在回答你的问题:

    这里有很多问题,其中大部分归结为“您将 null 传递给 cmo 它需要一个数组。”:

    • 您尝试在加载时运行函数,但未选择任何内容,这会将 null 传递给 cmo
    • 清空城镇&lt;select&gt; 也会触发其onChange 事件,将其空值传递给setHotel,然后传递给cmo
    • 您的数据中有名为“region”和“town”的额外键,而您在尝试匹配该数据时没有考虑这些键
    • 您的 HTML 中有一个重复的 ID,因此当您尝试检查酒店选择的值时,您却得到了其 label 的(不存在的)值
    • ...您的数据中有对象,您不小心尝试以数组形式访问。

    以下是修正版;我在更改您的代码的地方添加了 cmets:

    // renamed this, and removed the unneeded stringify-and-parse dance
    var jsonData = {
      "region": {
        "Warmińsko - mazurskie": {
          "town": {
            "Olsztyn": ["Mercury", "Novotel", "Sheraton", "Radisson", "Gołębiewski"],
            "Elbląg": ["Mercury", "Novotel", "Sheraton", "Radisson Blue", "Gołębiewski"],
            "Iława": ["Mer", "Novotel", "Sheraton", "Radisson", "Gołębiewski"],
            "Ostróda": ["Mercury", "Novotel", "Mariot", "Radisson", "Gołębiewski"],
            "Giżycko": ["Mercury", "Novotel", "Sheraton", "Vienna House", "Gołębiewski"],
          }
        },
        "Małopolskie": {
          "town": {
            "Kraków": ["Kossak", "Novotel", "Sheraton", "Radisson", "Stary"],
            "Tarnów": ["Mercury", "Novotel", "Sheraton", "Tarnovia", "Ibis"],
            "Oświęcim": ["Mercure", "Golden Tulip", "Sheraton", "Radisson", "Hampton"],
            "Skała": ["Focus", "Novotel", "Sheraton", "Radisson", "Zamek"],
            "Wieliczka": ["Mercurius", "Novotel", "Sheraton", "Arche", "Blue Star"],
          }
        },
        "Podlaskie": {
          "town": {
            "Białystok": ["Altus", "Deo", "Sheraton", "Radisson Blu", "Aquarion"],
            "Suwałki": ["Merr", "Novotel", "Ibis", "Radisson Red", "Arche"],
            "Łomża": ["Mercury 2", "Telios", "Sheraton", "Blue", "DeSilva"],
            "Augustów": ["Mariot", "Unicus", "Hampton", "Ibis Budget", "Ibis Styles"],
            "Zambrów": ["Golden", "Blue Star", "Sheraton", "Osteria", "Rafles"],
          }
        },
        "Podkarpackie": {
          "town": {
            "Rzeszów": ["Blue Star", "Notel", "Radius", "Puławski", "Grębiewski"],
            "Jasło": ["Mercury2", "Novotel2", "Sheraton2", "Radisson2", "Gołębiewski2"],
            "Krosno": ["Mercury3", "Novotel3", "Sheraton3", "Radisson3", "Gołębiewski3"],
            "Ustrzyki Górne": ["Mercury4", "Novotel4", "Sheraton4", "Radisson4", "Gołębiewski"],
            "Sanok": ["Mercury5", "Novotel5", "Sheraton5", "Radisson5", "Gołębiewski5"],
          }
        },
        "Mazowieckie": {
          "town": {
            "Warszawa": ["Mercury6", "Novotel6", "Sheraton6", "Radisson6", "Gołębiewski6"],
            "Sochaczew": ["Mercury7", "Novotel7", "Sheraton7", "Radisson7", "Gołębiewski7"],
            "Płock": ["Mercury8", "Novotel8", "Sheraton8", "Radisson8", "Gołębiewski8"],
            "Radom": ["Mercury9", "Novotel9", "Sheraton9", "Radisson9", "Gołębiewski9"],
            "Ciechanów": ["Mercury0", "Novotel0", "Sheraton0", "Radisson0", "Gołębiewski0"],
          }
        }
      }
    }
    
    var region = document.getElementById("region");
    var town = document.getElementById("town");
    var hotel = document.getElementById("hotel");
    
    // removed attempts to init while selects are all empty
    
    function setTown() {
      town.innerHTML = "";
      // corrected this line:
      let towns = Object.keys(jsonData.region[region.value].town);
      cmo(towns, town);
      setHotel();
    };
    
    function setHotel() {
      hotel.innerHTML = "";
      // corrected this line:
      let hotels = jsonData.region[region.value].town[town.value];
      cmo(hotels, hotel);
    };
    
    function cmo(arr, s) {
      if (arr.length) { // added this for safety: check if it's an array before you try to iterate over it
        arr.forEach(o => {
          let opt = document.createElement("option");
          opt.value = o;
          opt.innerHTML = o;
          s.add(opt);
    
        });
      }
    }
    <p><label for="region">Choose a region:</label>
      <select name="region" id="region" onchange="setTown();">
        <option disabled selected value="">Select a region</option>
        <option value="Warmińsko - mazurskie">Warmińsko - mazurskie</option>
        <option value="Małopolskie">Małopolskie</option>
        <option value="Podlaskie">Podlaskie</option>
        <option value="Podkarpackie">Podkarpackie</option>
        <option value="Mazowieckie">Mazowieckie</option>
      </select>
    </p>
    
    <p>
      <label for="town">Choose a town:</label>
      <select name="town" id="town" onchange="setHotel();">
      </select>
    </p>
    
    <p>
      <!-- changed this ID to not be a duplicate: -->
      <label for="hotel" id="hotelLabel">Choose a hotel:</label>
      <select name="hotel" id="hotel">
      </select>
    </p>

    【讨论】:

      猜你喜欢
      • 2017-04-24
      • 2022-10-18
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      • 2018-05-07
      • 2020-10-13
      • 2020-10-29
      • 2019-01-21
      相关资源
      最近更新 更多