在循环中附加小胡子模板

Append mustache templates in loop

我试图多次附加相同的小胡子模板,但每次都使用来自 php 通过 ajax 的不同值。这些值存储在数组中。

不幸的是,每个附加的模板都包含数组中最后一个条目的值。

如果我在循环末尾添加 alert("test");,它就可以工作。我必须等到追加功能完成吗?如果可以,我该怎么做?

谢谢!

$(document).ready(function postData() {
        var id = localStorage.getItem('user-id');
        var token = localStorage.getItem('user-token');
        var vars = "id=" + id + "&token=" + token;
        var hr = new XMLHttpRequest();
        var url = "../php/getUsers.php";

          hr.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                var data = JSON.parse(hr.responseText);

                for(var i=0;i<data.length;i++){

                        var templateData = {
                            name: data[i].name,
                            id: data[i].id

                        };
                      var id=templateData['id'];

                      $.get('templates/user.htm', function(templates) {

                            var template = $(templates).filter('#user-template').html();
                            $('#user-container').append(Mustache.render(template, templateData));
                        });
                 //alert("Test"); 
                 }
            }
        }
        hr.open("POST", url, true);
        hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        hr.send(vars);
    });

问题是当 $.get 调用的回调函数被调用时,templateData 已经在 for 循环的下一次迭代中改变。

要避免这种常见的关闭问题,您可以执行以下操作:

$.get('templates/user.htm', (function (templateData) {
    return function(templates) {
        var template = $(templates).filter('#user-template').html();
        $('#user-container').append(Mustache.render(template, templateData));
    }
})(templateData));

如果您使用的是ES2015,则不需要更改回调函数,因为您可以使用let代替var来定义templateData变量:

let templateData = {
    name: data[i].name,
    id: data[i].id

};

...

$.get('templates/user.htm', function(templates) {
    var template = $(templates).filter('#user-template').html();
    $('#user-container').append(Mustache.render(template, templateData));
});