首页 > 解决方案 > 如何在自动完成输入上设置 addEventListener 并提供多个源回调并一一使用

问题描述

我试图在输入上设置addEventListener,当它改变时我想用fetch api调用函数我有城市名称的自动完成输入,我的目标是通过选定的城市名称获取信息,其次,也许有人知道如何优化此代码调用回调并一一使用它们,直到回调的结果返回非空数组。

现在我输入了城市名称(由 api 获取 json),但控制台显示当我选择某个城市时输入值未定义

我有js文件:

let cities = document.querySelector("#languageList");
let cityInfoContainer = document.querySelector(".cityInfoContainer");
let input = document.querySelector("#txtAutoComplete");



  fetch("https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/cities.json")
  .then(res => res.json())
  .then((data) => {
     data.map(el=>cities.innerHTML += `<option value=${el.city}>`)
  })
  .catch(err => { throw err });


  let getCityInfo = (cityName) => fetch(`https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/data/${cityName.toLowerCase()}`)
  .then(res => res.json())
  .then((data) => {
    data.map(city => city.map(el=>cityInfoContainer.innerHTML += `<p> ${el.year}</p>`))
  })
  .catch(err => { throw err });

  input.addEventListener("change", getCityInfo(this.value))

和 HTML

    <header></header>
    <main class="cityInfo">
        <form>
            <input type="text" id="txtAutoComplete" list="languageList" />
            <datalist id="languageList">
            </datalist>
        </form>
        <div class="cityInfoContainer"></div>

    </main>
    <footer></footer>
    <script src="./dist/main.js"></script>
</body>```

标签: javascriptapiinputcallbackfetch

解决方案


  1. 你应该使用 Promises(或 async-await)
  2. 您忘记了City Info API 请求末尾的.json
  3. .map()返回一个新数组。您需要.forEach()来执行此功能
  4. 只需要一个.forEach()(所以不是地图中的地图),因为数组只有一层深

let cities = document.querySelector("#languageList");
let cityInfoContainer = document.querySelector(".cityInfoContainer");
let input = document.querySelector("#txtAutoComplete");

getCityNames()
  .then(data => {
    data.map(el => cities.innerHTML += `<option value=${el.city}>`)
  })

input.addEventListener("change", function(e) {
  getCityInfo(this.value)
    .then(data => {
      console.log(data)
      // this clears the area for the new city selected
      if (cityInfoContainer.innerHTML !== '') {
        cityInfoContainer.innerHTML = ''
      }
      data.forEach(city => cityInfoContainer.innerHTML += `<p> ${city.year} ${city.population}</p>`)
    })
    .catch(err => {
      console.log('err', err)
    })
})

function getCityNames() {
  return new Promise((resolve, rejecet) => {
    fetch("https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/cities.json")
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}

function getCityInfo(cityName) {
  return new Promise((resolve, reject) => {
    fetch(`https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/data/${cityName.toLowerCase()}.json`)
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}
<main class="cityInfo">
  <form>
    <input type="text" id="txtAutoComplete" list="languageList" />
    <datalist id="languageList">
            </datalist>
  </form>
  <div class="cityInfoContainer"></div>

</main>

至于一一调用,直到下载所有信息:

let cities = document.querySelector("#languageList");
let cityInfoContainer = document.querySelector(".cityInfoContainer");
let input = document.querySelector("#txtAutoComplete");

// adding an array that will hold all the cities' names
let cityNameArr = []

getCityNames()
  .then(data => {
    data.forEach(el => cities.innerHTML += `<option value=${el.city}>`)
    return data.map(el => {
      return {
        cName: el.city
      }
    })
  })
  .then(cityNames => {
    return cityNames.map(el => {
      return {
        cName: el.cName,
        cInfo: getCityInfo(el.cName)
      }
    })
  })
  .then(city => {
    console.log(city) // expected to see "cInfo: Promise" - until it's resolved
  })



input.addEventListener("change", function(e) {
  getCityInfo(this.value)
    .then(data => {
      console.log(data)
      // this clears the area for the new city selected
      if (cityInfoContainer.innerHTML !== '') {
        cityInfoContainer.innerHTML = ''
      }
      data.forEach(city => cityInfoContainer.innerHTML += `<p> ${city.year} ${city.population}</p>`)
    })
    .catch(err => {
      console.log('err', err)
    })
})

function getCityNames() {
  return new Promise((resolve, rejecet) => {
    fetch("https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/cities.json")
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}

function getCityInfo(cityName) {
  return new Promise((resolve, reject) => {
    fetch(`https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/data/${cityName.toLowerCase()}.json`)
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}
<main class="cityInfo">
  <form>
    <input type="text" id="txtAutoComplete" list="languageList" />
    <datalist id="languageList">
            </datalist>
  </form>
  <div class="cityInfoContainer"></div>

</main>


推荐阅读