开发者

Jquery DOM not updating after .each() iteration

I am trying to keep track of updates as the each iterates and when the each is finished I would like to show a summary to the user in a graceful way. I have tried almost everything to a method call to update an element on the page but unless I fire off an alert at any point in the event call it will not update.

If anyone knows what I may be missing I would like to see how it is done. Big THANKS in advance!

$('#button-restore-projects').live("click", function() {
                    var countSuccess = 0
                    , countError = 0
                    , element = $("#selectedProjects option")
                    , eachCount = element.length;
                    $("#countReady").html(eachCount);

                    $.each(element, function(i, o) {
                        var id = $(this).val();
                        //alert(i);
                        $.ajax({
                            type: "POST",
                            url: RestoreProject,
                            data: "plan=<%= Model.RtpSummary.RtpYear %>"
                                + "&id=" + id,
                            dataType: "json",
                            success: function(response, textStatus, XMLHttpRequest) {
                                if (response.error == "false") {
                                    //$('').html(response.message);
                                    //$('').addClass('success');
                                    //autoHide(2500);
                                    oProjectListGrid.fnAddData([
                                        "<a href=\"/RtpProject/" + response.data.RtpYear + "/Info/" + response.data.ProjectVersionId + "\">" + response.data.Title + "</a>",
                                        response.data.PlanType,
                                        response.data.COGID,
                                        response.data.TIPId,
                                        response.data.ImprovementType,
                                        response.data.SponsorAgency,
                                        response.data.AmendmentStatus,
                                        response.data.ProjectVersionId]);
                                    countSuccess++;
                                    removeProject(id, false, null);
                                } else {
                                    countError++;
                                    //$('.dialog-result').html(response.message + " Details: " + response.exceptionMessage);
                                    //$('.dialog-result').addClass('error');
                                    //autoHide(10000);
                                }
                                window.onbeforeunload = null;
                            },
                            error: function(response, textStatus, AjaxException) {
                                //alert("error");
                                countError++;
                                //$('').html(response.statusText);
                                //$('').addClass('error');
                                //autoHide(10000);
                            }
                        });
                        //alert(eachCount);
                        //eachCount--;
                        $("#countReady").text(eachCount + ", " + countError + ", " + countSuccess);
                        //alert(eachCount + ", " + countError + ", " + countSuccess);

                        if (eachCount-1 == i) { showRestoreResponse(countError, countSuccess); }
                    });
                    //alert("test");


                    return false;
                });

SOLUTION!!!

First many thanks to all and specifically @SLaks! Second, http://james.padolsey.com/javascript/monitoring-dom-properties/ is credited for a small plugin to monitor an object.

What I did was convert my original variables to an object that was essentially watched. Using the jquery plugin from above I watched the object for a condition: newVal == 0, where newVal is the new value of the eachCount. That watch hit every millisecond waiting for all the server responses to come back to me with error or success. When finished I display a nice little summary report of the actions that happened.

I'm not too sure if this was the best way but it looks good on the screen and my eyes dont hurt too bad looking at it. Below is my solution. Later I will add in the suggestions for keeping an active record update of what is left in the queue. All that code was primarily the debugging that I was adding.

$('#button-restore-projects').live("click", function() {

                var element = $("#selectedProjects option");

                var obj = { eachCount: element.length, countSuccess: 0, countError: 0 };
                //$("#countReady").html(eachCount);

                $.each(element, function(i, o) {
                    var id = $(this).val();
                    //alert(i);
                    $.ajax({
                        type: "POST",
                        url: RestoreProject,
                        data: "plan=<%= Model.RtpSummary.RtpYear %>"
                            + "&id=" + id,
                        dataType: "json",
                        success: function(response, textStatus, XMLHttpRequest) {
                            if (response.error == "false") {
                                //$('').html(response.message);
                                //$('').addClass('success');
                                //autoHide(2500);
                                oProjectListGrid.fnAddData([
                                    "<a href=\"/RtpProject/" + response.data.RtpYear + "/Info/" + response.data.ProjectVersionId + "\">" + response.data.Title + "</a>",
                                    response.data.PlanType,
                                    respon开发者_如何学编程se.data.COGID,
                                    response.data.TIPId,
                                    response.data.ImprovementType,
                                    response.data.SponsorAgency,
                                    response.data.AmendmentStatus,
                                    response.data.ProjectVersionId]);
                                obj.eachCount--;
                                obj.countSuccess++;
                                removeProject(id, false, null);
                            } else {
                                obj.countError++;
                                //$('.dialog-result').html(response.message + " Details: " + response.exceptionMessage);
                                //$('.dialog-result').addClass('error');
                                //autoHide(10000);
                            }
                            window.onbeforeunload = null;
                        },
                        error: function(response, textStatus, AjaxException) {
                            //alert("error");
                            obj.countError++;
                            //$('').html(response.statusText);
                            //$('').addClass('error');
                            //autoHide(10000);
                        }
                    });
                    //$("#countReady").text(eachCount + ", " + countError + ", " + countSuccess);
                });

                $(obj).watch('eachCount', function(propName, oldVal, newVal) {
                    //alert(newVal);
                    if (newVal == 0) {
                        showRestoreResponse(obj.countError, obj.countSuccess);
                    }
                });

                return false;
            });


$.ajax is an asynchronous call which returns immediately.
The success callback is called later, after the server replies.

Therefore, after your each loop, none of the success callbacks have run yet.


The problem looks like it could lie in

$("#countReady").text(eachCount + ", " + countError + ", " + countSuccess);

This needs to be called when the success and error is called inside the ajax function.


Also this really isn't the best way of doing it. Really you should use a ajax connection with keep-alive and send the data in one POST then periodically have your PHP script send back the latest status in JSON format: { "countSuccess": "5", "countError", "0", "current": "5", "total": "10" } then when current == total you know it's complete, show an information div detailing the results. :)

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜