2010-09-07 4 views
1

J'essaie de garder une trace des mises à jour car chaque itération et quand chacune est terminée, je voudrais montrer un résumé à l'utilisateur d'une manière gracieuse. J'ai essayé presque tout à un appel de méthode pour mettre à jour un élément sur la page mais à moins que je déclenche une alerte à tout moment dans l'appel d'événement il ne mettra pas à jour.Jquery DOM ne se met pas à jour après .each() itération

Si quelqu'un sait ce que je pourrais manquer je voudrais voir comment cela est fait. Merci d'avance!

$('#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 !!!

Tout d'abord merci à tous et en particulier @SLaks! Deuxièmement, http://james.padolsey.com/javascript/monitoring-dom-properties/ est crédité pour un petit plugin pour surveiller un objet.

Ce que j'ai fait était convertir mes variables d'origine en un objet qui a été essentiellement regardé. En utilisant le plugin jquery ci-dessus, j'ai regardé l'objet pour une condition: newVal == 0, où newVal est la nouvelle valeur de eachCount. Cette montre a frappé toutes les millisecondes en attendant que toutes les réponses du serveur me reviennent avec une erreur ou un succès. Une fois terminé, j'affiche un joli petit résumé des actions qui ont eu lieu.

Je ne sais pas trop si c'était le meilleur moyen mais ça a l'air bien sur l'écran et mes yeux ne me font pas trop mal à le regarder. Voici ma solution. Plus tard, je vais ajouter dans les suggestions pour garder une mise à jour active de l'enregistrement de ce qui reste dans la file d'attente. Tout ce code était principalement le débogage que j'ajoutais.

$('#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, 
            response.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; 
      }); 

Répondre

1

$.ajax est un appel asynchrone qui renvoie immédiatement.
Le rappel success est appelé ultérieurement, après que le serveur a répondu. Par conséquent, après votre boucle each, aucun rappel success n'a encore été exécuté.

+0

Si je parcours le code, je le vois démarrer et mettre à jour la base de données. Donc, vous dites que le succès attend jusqu'à ce que chaque fonction est terminée – Tuck

+0

Sort of. Le rappel 'success' n'est appelé qu'après la réponse du serveur, ce qui se produit généralement après la fin de l'appel' each'. – SLaks

+0

Avancer pour trouver un moyen de surveiller les appels ajax à compléter. Vous êtes sur la bonne voie avec la solution. – Tuck

0

Le problème semble que cela pourrait se situer dans

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

Cela doit être appelé quand le succès et l'erreur est appelée dans la fonction ajax.


Ce n'est vraiment pas la meilleure façon de le faire. Vraiment, vous devez utiliser une connexion ajax avec keep-alive et envoyer les données dans un POST puis périodiquement avoir votre script PHP renvoyer le dernier état au format JSON: { "countSuccess": "5", "countError", "0", "current": "5", "total": "10" } puis quand actuel == total vous savez qu'il est complet, afficher une div d'information détaillant les résultats . :)

+0

Cela pourrait être. Ce que je prépare maintenant est une montre à surveiller lorsque les appels ajax sont terminés, puis déclenche une méthode pour montrer les résultats. Le code auquel vous faites référence a l'air de l'avoir mis au mauvais endroit. Merci. – Tuck

+0

Fondamentalement, vous devez mettre le '.text() 'Fonction de mise à jour lorsque les données sont reçues i.e dans vos fonctions' success() 'et' error() '. Créez simplement une nouvelle fonction comme 'var showStatus = function() {$ (" # countReady "). Text (chaqueCompte +", "+ countError +", "+ countSuccess); } 'alors appelez' showStatus() 'dans vos fonctions succès/erreur. –

Questions connexes