javascript - 如何在自动完成输入上设置 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>```
解决方案
- 你应该使用 Promises(或 async-await)
- 您忘记了City Info API 请求末尾的.json
- .map()返回一个新数组。您需要.forEach()来执行此功能
- 只需要一个.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>
推荐阅读
- sql - 在 T-Sql 中使用用户定义的数据类型识别所有存储过程和表
- wget - 使用 wget 递归获取 .php 文件中的 .txt 文件,但过滤器会破坏命令
- node.js - 找不到模块“install-npm-version”
- c# - C# - 返回 PayDate 最低但 ReconciliationDate 最高的记录
- c++ - 我需要使用哈希表创建 MultiMap,但出现超出时间限制的错误(C++)
- javascript - 需要 CanvasRenderingContext2D 作为父对象才能运行
- java - 如何在 java 中使用 Gmail API 回复邮件?
- ruby - Jekyll:在不使用外部插件的情况下获取图像的宽度/高度
- python - 我对我的 Python 感到困惑。ValueError:对已关闭文件的 I/O 操作
- excel - 使用 PowerShell 在 Excel 中批量添加超链接