ajax回调中的闭包循环

时间:2016-09-10 03:41:30

标签: javascript jquery ajax closures

我有一个从json解析的数据,我在Facebook的朋友建议框中显示数据。我希望当用户点击任何建议用户时,通过ajax将请求添加到DB并且其相应的按钮消失,一切正常,除了最后一件事(按钮消失)而不是列表中的第一个按钮消失虽然我正在寻找我的问题的解决方案,但我遇到了一个名为closure 的东西,但是我真的不知道如何在我的代码中实现它,当我试图声明监听器时出现了另一个问题循环内部的匿名函数是数据多次插入DB中 (因为它在一个循环中),我知道这似乎是重复的问题,但我只需要有人指出我正确的地方来宣布我的内在功能,

我的代码看起来像这样

$(document).ready(function() {
    var suggest = new XMLHttpRequest();
    suggest.onreadystatechange = function() {
        if (suggest.readyState === 4 && suggest.status === 200) {
            var susers = JSON.parse(suggest.responseText);

            for (var i = 0; i < susers.length; i += 1) {
                var sphoto = '<div class="col-md-4 text-left  "> <div id="fimage">';
                sphoto += '<img  width="50" height="50" src="user/';
                sphoto += susers[i].activation + '/' + susers[i].pic + '"> </div>   </div>';
                var sname = '<div id="fname">' + susers[i].name + '</div>';

                // here is the form im targetting to pull informtion from
                var hidden = '<form id="fform"><input id="fnameh" name="name" type="hidden" value="' + susers[i].name + '" >';
                hidden += '<input name="id" type="hidden" value="' + susers[i].id + '" >';

                var fbutton = '<button  id="addfriend"class="btn btn-info  btn-xs pull-right text-center" type="submit" >Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button></form';


                var display = document.getElementById('fsuggest');
                display.innerHTML += '<div class="scroller"><div id="fspace" > <button  type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + sphoto + sname + hidden + fbutton +'</div></div>'

                $('#addfriend').live('click', function(arg) {
                    return function() {
                        arg.preventDefault();
                        var data = $('#fform').serialize();
                        $.ajax({
                            data: data,
                            type: "post",
                            url: "addnew.php",
                            success: function(data) {
                             //make the text area empty
                              $('#addfriend').css("display", "none");
                                console.log(data);
                            }

                        }); // end of $.ajax

                    }(i); // end of inner function

                }); // end of click listner 



            } //end of for loop

       }
    };

    suggest.open('GET', 'box.php');
    suggest.send();
}); // end of JQUERY ready

2 个答案:

答案 0 :(得分:0)

我不确定为什么你需要closure。这个问题似乎与多种形式有关。具有相同id的按钮。

所有这些按钮都具有相同的id,因此forms。所以

$('#addfriend').live('click', function(arg) {..}) has no reference to the particular button 

希望这一改变有所帮助

i的值与表格&amp;的ID相对应。添加属性data-id=i按钮。

除了id而不是id添加类addfriend到按钮。因此,当单击此按钮时,请取data-id值。使用此值可以获得带有id和&amp ;;的相关表单。序列化

var hidden = '<form id="fform_' + i + '"><input id="fnameh" name="name" type="hidden" value="' + susers[i].name + '" >';
hidden += '<input name="id" type="hidden" value="' + susers[i].id + '" >';


var fbutton = '<button data-id="' + i + '" id=""class=" addfriend btn btn-info  btn-xs pull-right text-center" type="submit" >Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button>';

在下方更改点击功能。

在循环中添加事件处理程序的原因还不明确。

 $('.addfriend').live('click', function(arg) {
           arg.preventDefault();
           var getDataId = $(this).attr('data-id')  // get the data-id
            var data = $('#fform_'+getDataId).serialize(); // get relevant form
            $.ajax({
              // rest of code
           }); // end of $.ajax
           })

尝试使用1.9以上的jquery版本来使用on方法进行事件委派

答案 1 :(得分:0)

我对您的代码进行了一些更改。

使用新的javascript,我相信大多数浏览器本身都支持字符串插值(例如,没有任何额外的插件或使用babel进行预编译),因此您可以在反引号中插入变量``。

此外,您似乎正在为每次迭代创建一个id为#fform的表单和一个id为#addfriend的按钮。问题是调用$('#fform')$('#addfriend')将返回一个包含与用户一样多的元素的数组。

所以我添加了一个额外的data-suser-id属性,其中包含唯一的id个。{我不确定代码是否有效,因为我实际上无法尝试并更改了一些内容,但如果您越来越接近解决方案,请告诉我。

    $(document).ready(function() {
        var suggest = new XMLHttpRequest();
        suggest.onreadystatechange = function() {
            if (suggest.readyState === 4 && suggest.status === 200) {
                var susers = JSON.parse(suggest.responseText);
                var limit = susers.length;
                for (var i = 0; i < limit; i += 1) {
                    var sphoto = `<div class="col-md-4 text-left  ">
                                    <div id="fimage">
                                        <img  width="50" height="50" src="user/${susers[i].activation}/${susers[i].pic}">
                                    </div>
                                </div>`
                    var sname = `<div id="fname">${susers[i].name}</div>`
                    // here is the form im targetting to pull informtion from
                    var hidden     = `<form id="fform" data-suser-id='${susers[i].id}'>
                                        <input id="fnameh" name="name" type="hidden" value="${susers[i].name}" >
                                        <input name="id" type="hidden" value="${susers[i].id}">`
                    var mutalusers = `</form><div id="mutal" class="text-left">
                                        <h6>
                                            <div id="fmutal">
                                                <?php echo $c = mutal(${susers[i].id}, $me, $db) ?>
                                            </div>
                                        </h6>
                                    </div>`
                    var fbutton = `<button id="addfriend" class="btn btn-info btn-xs pull-right text-center" type="submit" data-suser-id='${susers[i].id}'>Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button>`;
                    var display = document.getElementById('fsuggest');
                    display.innerHTML += `<div class="scroller">
                                            <div id="fspace">
                                                <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                    <span aria-hidden="true">&times;</span>
                                                </button>
                                                ${sphoto}
                                                ${sname}
                                                ${hidden}
                                                ${fbutton}
                                                ${mutalusers}
                                            </div>
                                        </div>`
                        // #live method is deprecated : http://api.jquery.com/live/
                    var addfriend_button = $(`#addfriend[data-suser-id=${susers[i].id}]`)
                    addfriend_button.on('click', function(arg) {
                        // return function(){
                        arg.preventDefault();
                        // the selector `#fform` doesn't seem to be unique to the current user's form data, so I added an data-attribute to make sure we are getting the correct form data
                        var data = $(`#fform[data-suser-id=${susers[i].id}]`).serialize();
                        $.ajax({
                            data: data,
                            type: "post",
                            url: "addnew.php",
                            success: function(data) {
                                //make the text area empty for the current user's `#addfriend` button
                                addfriend_button.html('done');
                                console.log(data);
                            }
                        }); // end of $.ajax
                        // }(i); // end of inner function : not sure why this inner function is necessary
                    }); // end of click listner
                } //end of for loop
                console.log(susers);
            }
        };
        var suugestFile = 'box.php';
        suggest.open('GET', suugestFile);
        suggest.send();
    }); // end of JQUERY ready