我有一个Algolia索引,其数据如下:
id:FirstLastNumber
name:First Name
objectID:FirstLastNumber
address:1234 Fake Street
city:New York
state:NY
我查询并将结果转储到这样的页面上:
algoliaIndex.search({
query: input
}, function searchDone(error, content) {
if (error) {
console.log(error);
return;
}
var results = document.getElementById('results');
for (var hit in content.hits) {
var resultName = content.hits[hit].name;
var resultCity = content.hits[hit].city;
var resultID = content.hits[hit].id
var resultItem = document.createElement('a');
resultItem.className = "collection-item";
resultItem.innerHTML = "<div class='list-text'><span
class='title-in-list'>" + resultName + "</span><br><span
class='date-in-list'>" + resultCity + "</span></div>";
resultItem.onclick = function() {
//pull details for the member.
getMember(resultID);
};
results.appendChild(resultItem);
};
});
其中95%完全符合预期。但是,对于onclick
函数,它会将最后一个结果的ID放在每个resultItem
中。因此,当我单击任何结果时,它会提取结果列表中最后一个成员的详细信息。例如,如果我有3个结果,无论我点击什么结果,最后一个结果的ID都会传递给getMember()
。无论我使用id键还是objectID键,都会发生这种情况。我在这里做错了什么?
我使用相同的代码将Firebase中的数据提取到一个不同的,虽然是理想编写的成员列表中,但它的工作正常。如果我这样做,我可以让Algolia部分工作:
resultItem.id = resultID;
resultItem.onclick = function(event) {
getMember(event.srcElement.id);
};
如何从Algolia返回的id或objectID坚持相应的项目?
答案 0 :(得分:1)
问题是由于javascript作用域的工作原理。尽管看起来好像是在每个键迭代上创建一个具有不同foreach (DataRow r in dt.Rows.Cast<DataRow>().Skip(1)
.Where(o => !string.IsNullOrEmpty(o["Column"].ToString())))
{
...
}
的函数,但事实并非如此。由于resultId
由外部resultId
变量确定,并且由于hit
在每个循环中被覆盖,因此您最终会对同一个hit
变量进行多次引用,因此为什么您总是会看到循环中hit
设置为的最后一个ID的返回值。
一种解决方案是在函数中包装onClick函数声明,以便在每次迭代时在不同的hit
值上创建一个闭包。也许这会奏效:
hit
答案 1 :(得分:1)
这是范围问题。在循环中,命中变量的范围是全局的。您可以将for循环中的代码包装在一个闭包中,该闭包在循环中捕获hit
的值,或者如果使用ES6功能,则可以使用let
而不是var
for (var hit in content.hits) {
(function(){
//the code you had inside the for loop
})(hit);
}
for (let hit in content.hits)