开发者

JS / AJAX / JSON

开发者 https://www.devze.com 2023-03-27 21:55 出处:网络
I\'m new to JS / AJAX and JSON parsing.I\'ve been trying to debug this code snippet for a while now and I can\'t seem to figure it out.

I'm new to JS / AJAX and JSON parsing. I've been trying to debug this code snippet for a while now and I can't seem to figure it out.

I'm trying to append the values to dynamic divs but the $("#" + id) inside the AJAX request always has the last value of the id inside the for loop. It's not appending it every time the for loop increments to the next value of the div id.

Anyone know what is wrong? or are AJAX requests like this?

The var myID a开发者_如何学Pythont the end was for debugging. The myID gets the value of the id fine but the AJAX request doesn't seem to execute until the last value of the for loop is running.

Any help would be appreciated.

    for (var x = 0; x < days.length; x++) {
            var y = days[x];
            var id = location + "_day_" + y;
            $("#" + location).append("<div id='" + id + "'><h2>Day #" + y + "</h2></div>");

            $.ajax
            ({
                type: "GET",
                url: jsonFile,
                dataType: "json",
                success: function(json) {

                    for (var i = 0; i < json.trips.length; i++) {
                        var name = json.trips[i].name;
                        var cost = json.trips[i].cost;

                        radioButton = "<label><input type='radio' name='day_" + y + "' />" + name + " - $" + cost + ".00</label><br>";
                        $("#" + id).append(radioButton);
                    }
                }
            });
            var myID = id;
    }


That is because the Ajax callback doesn't get called until later (after the request finished) and by that time the value of id will be the last value in the loop. You need to use a closure to solve this problem:

{
   type: "GET",
   url: jsonFile,
   dataType: "json",
   success: (function(id){
            return function(json) {

                for (var i = 0; i < json.trips.length; i++) {
                    var name = json.trips[i].name;
                    var cost = json.trips[i].cost;

                    radioButton = "<label><input type='radio' name='day_" + y + "' />" + name + " - $" + cost + ".00</label><br>";
                    $("#" + id).append(radioButton);
                }
            };
        })(id)
}

Now the function gets passed id as a local variable, instead of using the variable in the outer scope which has changed since you made this function.

To help you understand, here is an example of what is happening to you: http://jsfiddle.net/qXCKZ/ Notice how the new value of id is alerted.

Here is the solution which creates a local copy of the variable by using a closure: http://jsfiddle.net/DAwNz/


Have you tried moving the content of the for-loop into a separate function? I think there is a closure-binding issue there, although it would be expected for the id to be the same value as when you invoked the ajax function. Moving all the content into a separate function would bind the id variable to the scope of the function.


Ajax requests are asynchronous, meaning the request is started when you make the $.ajax call, but it keeps going through the code instead of waiting for a response. A for loop is very quick, so by the time the ajax request has come back, the for loop has already made it to the end. Also, because the ID variable is local to the containing function, it will not get used until the success function is called.

To solve this, use a closure. This will let you pass in the value of the ID variable at the moment that you make the ajax call.

For example:

$.ajax({
  ...
  success: (function (id) {
      return function(json) {
        ...
      }
    }(id));
});

Having the (id) at the end of that function executes the function as soon as the code is processed and it makes id a local variable to that context. It then returns the callback function that you were trying to define in the first place.

Hope that helps. :)


If he just adds the async: false property to the call. then this will work.

0

精彩评论

暂无评论...
验证码 换一张
取 消