我根据查询数据库的AJAX请求返回的JSON对象动态创建了很多按钮。
然后每个按钮需要对相同的数据库进行后续的AJAX调用,具体取决于我放入每个按钮的onClick函数的信息。
基本上,网址为"api/"
,如果我只调用foo
,则会为"api/book/"
提供所有可能的选项。如果我致电bar
,它会为foo = "book"
//getJSON is a promise function that returns a JSON object
getJSON("api")
// volumes is the JSON object that contains an array of objects
// each object is {book:"someTitle",url:"titleShorthand"}
.then((volumes) => {
for (var vol in volumes) {
//create Button returns a document.crateElement(input)
//with type=button and value = the passed in param.
var btn = createButton(volumes[vol].book)
btn.addEventListener('click', function(){
getJSON("api/" + volumes[vol].url)
.then((books) => {
console.log(books)
})
})
volumeDiv.appendChild(btn)
}
})
提供所有可能的选项,等等......
console.log(books)
所有的button.onClick事件都是一样的,因为volumes[vol].url
只给我最后一套书,无论我点击哪个按钮。对于每个按钮而言,{{1}}似乎都会被for循环的每次迭代重写,而不仅仅是新创建的按钮。
答案 0 :(得分:0)
那是因为您在for
循环内声明了一个函数。由于closures的工作原理,volume[vol]
的值始终是您在循环中声明的函数运行时的最后一个值。
要解决此问题,您可以使用higher order function。
我不得不模拟一些函数来使这个代码段工作,但是您必须在代码中编写类似getEventListener
的函数才能使其正常工作。
var volumeDiv = document.getElementById('container')
function getJSON (url) {
return new Promise (resolve => {
var vol1 = {
book: "vol1",
url: "vol1"
}
var vol2 = {
book: "vol2",
url: "vol2"
}
var map = {
'api': { vol1, vol2 },
'api/vol1': vol1,
'api/vol2': vol2
}
resolve(map[url])
})
}
function createButton (name) {
console.log(`creating button ${name}`)
var btn = document.createElement('input')
btn.type = 'button'
btn.value = name
return btn
}
function getEventListener (url) {
return () => {
getJSON(url)
.then((books) => {
console.log(books)
})
}
}
getJSON("api")
.then(volumes => {
for (var vol in volumes) {
var volumeUrl = volumes[vol].url
var btn = createButton(volumes[vol].book)
btn.addEventListener('click', getEventListener("api/" + volumeUrl))
volumeDiv.appendChild(btn)
}
})

<div id="container" />
&#13;