通过Algolia迭代命中覆盖每个ID,其ID为最后结果

时间:2017-12-15 02:27:24

标签: javascript algolia

我有一个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坚持相应的项目?

2 个答案:

答案 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

选项1

for (var hit in content.hits) {
  (function(){
    //the code you had inside the for loop
  })(hit);
}

选项2

for (let hit in content.hits)