2016-05-25 13 views
3

Ich habe zur Zeit eine AJAX to PHP-Gruppe von Funktionen eingerichtet, die eine Reihe von Elementen auf einer Seite verarbeitet. Im Wesentlichen fügt der Code eine Reihe von Aufgaben in die Datenbank ein und fügt anschließend in die Datenbank basierend auf diesen neu erstellten Aufgaben-IDs Ressourcen ein. Es funktioniert jedoch 90% der Zeit. Manchmal scheint es, als ob die Aufgaben-IDs nicht zuerst erstellt werden, was es den Verbrauchsmaterialien nicht erlaubt, diese IDs zum Einfügen in die Datenbank zu verwenden. Gibt es eine Möglichkeit, um sicherzustellen, dass die Aufgabe eingefügt wird, dann werden alle Verbrauchsmaterialien für diese ID eingefügt und dann auf die nächste übertragen. Am Ende, wenn alles fertig ist, möchte ich auf eine neue Seite umleiten, wieder habe ich dies beim letzten Erfolgsaufruf auf den Zubehörteil gesetzt, aber es würde auf der ersten Schleife umgeleitet. Dieser Prozess generiert normalerweise ungefähr 5 Aufgaben mit 12 Vorräten pro Aufgabe. Ich habe über eine $.when-Schleife gelesen, konnte sie aber nicht zum Laufen bringen. HINWEIS: Nach dem Testen der Ajax-Aufrufe, die korrekt gesendet werden, war es so, dass ein Feld bei einigen von ihnen null war und die DB ein Problem hatte. So funktioniert die folgende Counter-Methode.So warten Sie, bis AJAX-Aufrufe in einer einzelnen Schleife abgeschlossen sind, bevor Sie ohne ASYNC fortfahren: FALSE

$(document).on("click", "#submitTasks", function(e) { 
    e.preventDefault(); 
    var tasks = $('#tasks').find('.box'); 
    var project_id = $('#project_id').val(); 
    tasks.each(function() { 
     var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr'); 
     var task_definition_id = $(this).find('.task_definition_id').val(); 
     var labor_type_id = $(this).find('.laborAmount').children('option:selected').val(); 
     var task_status_id = 1; 
     var qty_labor = $(this).find('.laborQty').val(); 
     var amount_labor = $(this).find('.laborTotal').val(); 
     var amount_materials = $(this).find('.matTotal').val(); 
     var amount_gst = $(this).find('.gstTotal').val(); 
     amount_materials = +amount_materials + +amount_gst; 
     amount_materials = amount_materials.toFixed(2); 
     var active = 1; 
     //console.log(div) 
     var task = { 
      project_id : project_id, 
      task_definition_id : task_definition_id, 
      labor_type_id : labor_type_id, 
      task_status_id : task_status_id, 
      qty_labor : qty_labor, 
      amount_labor : amount_labor, 
      amount_materials : amount_materials, 
      active : active 
     }; 
     saveTasks(task, trs, project_id); 
    }); 
}); 
function saveTasks(task, trs, project_id) { 
    $.ajax({ 
     type : "POST", 
     url : "<?php echo base_url(); ?>" + "mgmt/project/saveTasks", 
     data : task, 
     dataType : "json", 
     cache : "false", 
     success : function(data) { 
      trs.each(function() { 
       var total = $(this).find('input[name="calculatedCost"]').val(); 
       if (total != 'n/a') { 
        var task_id = data; 
        var supply_id = $(this).find('.suppliesPicker').children('option:selected').val(); 
        var task_requirement_id = $(this).find('td:first-child').data('id'); 
        var qty = $(this).find('input[name="calculatedQty"]').val(); 
        var cost_per = $(this).find('.costPicker').val(); 
        var delivery_cost = $(this).find('input[name="transport"]').val(); 

        var notes = ''; 
        var qty_actual = ''; 
        var active = 1; 
        var taskSupply = { 
         task_id : task_id, 
         supply_id : supply_id, 
         task_requirement_id : task_requirement_id, 
         qty : qty, 
         cost_per : cost_per, 
         delivery_cost : delivery_cost, 
         total : total, 
         notes : notes, 
         qty_actual : qty_actual, 
         active : active 
        }; 
        saveTaskSupplies(taskSupply); 
        console.log(taskSupply); 
       } 
      }); 
     } 
    }); 
} 

function saveTaskSupplies(taskSupply) { 
    $.ajax({ 
     type : "POST", 
     url : "<?php echo base_url(); ?>" + "mgmt/project/saveTaskSupplies", 
     data : taskSupply, 
     dataType : "json", 
     cache : "false", 
     success : function(data) { 
      ***** I WANT TO REDIRECT TO A NEW PAGE WHEN THE LAST ONE OF THESE COMPLETES ****** 
     } 
    }); 
}  
+0

Mögliche Duplikat [Warten Sie, bis alle Anfragen jQuery Ajax getan werden?] (Http://stackoverflow.com/questions/3709597/wait-until-all-jquery-ajax-requests-are-done) – Seth

+0

Ich habe versucht, diese Arbeit zu machen, jedoch nicht alle Anfragen zur gleichen Zeit passiert. Es gibt eine Funktion in der ersten Schleife, die eine zweite Funktion 12 Mal aufruft, dann durchläuft die erste Schleife ein zweites Mal und ruft diese zweite Funktion 10 Mal auf. Dieses '.when' sieht aus, was ich brauche, aber wo würde ich es einfügen.Ich habe versucht, die when-Schleife auf 'saveTasks (task, trs, project_id)' und auf 'saveTaskSupplies (taskSupply);' aber das scheint nicht zu funktionieren – user1881482

+0

Grundsätzlich müssen Sie Zähler hinzufügen, um zu verfolgen, wie viele Elemente, die Sie verarbeitet haben, und sobald der verarbeitete Wert == Gesamtanzahl ist, fahren Sie fort. Ich arbeite eine vollständige Antwort. – cyberbit

Antwort

2

Hier ist eine direkte Lösung mit dem von Ihnen bereitgestellten Code. Das Grundkonzept besteht darin, einen Zähler zu erhöhen, wenn Vorräte verarbeitet werden. Sobald der Zähler die Gesamtzahl der Lieferungen erreicht hat, wird eine Prozedur ausgeführt. Siehe Kommentare überall.

var totalTaskSupplies = 0; 
var processedTaskSupplies = 0; 

$(document).on("click", "#submitTasks", function(e) { 
    e.preventDefault(); 
    var tasks = $('#tasks').find('.box'); 
    var project_id = $('#project_id').val(); 

    tasks.each(function() { 
     var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr'); 
     var task_definition_id = $(this).find('.task_definition_id').val(); 
     var labor_type_id = $(this).find('.laborAmount').children('option:selected').val(); 
     var task_status_id = 1; 
     var qty_labor = $(this).find('.laborQty').val(); 
     var amount_labor = $(this).find('.laborTotal').val(); 
     var amount_materials = $(this).find('.matTotal').val(); 
     var amount_gst = $(this).find('.gstTotal').val(); 

     // Add number of supplies for current task to total task supplies 
     totalTaskSupplies += trs.length; 

     amount_materials = +amount_materials + +amount_gst; 
     amount_materials = amount_materials.toFixed(2); 
     var active = 1; 
     //console.log(div) 
     var task = { 
      project_id : project_id, 
      task_definition_id : task_definition_id, 
      labor_type_id : labor_type_id, 
      task_status_id : task_status_id, 
      qty_labor : qty_labor, 
      amount_labor : amount_labor, 
      amount_materials : amount_materials, 
      active : active 
     }; 
     saveTasks(task, trs, project_id); 
    }); 
}); 
function saveTasks(task, trs, project_id) { 
    $.ajax({ 
     type : "POST", 
     url : "<?php echo base_url(); ?>" + "mgmt/project/saveTasks", 
     data : task, 
     dataType : "json", 
     cache : "false", 
     success : function(data) { 
      trs.each(function() { 
       var total = $(this).find('input[name="calculatedCost"]').val(); 
       if (total != 'n/a') { 
        var task_id = data; 
        var supply_id = $(this).find('.suppliesPicker').children('option:selected').val(); 
        var task_requirement_id = $(this).find('td:first-child').data('id'); 
        var qty = $(this).find('input[name="calculatedQty"]').val(); 
        var cost_per = $(this).find('.costPicker').val(); 
        var delivery_cost = $(this).find('input[name="transport"]').val(); 

        var notes = ''; 
        var qty_actual = ''; 
        var active = 1; 
        var taskSupply = { 
         task_id : task_id, 
         supply_id : supply_id, 
         task_requirement_id : task_requirement_id, 
         qty : qty, 
         cost_per : cost_per, 
         delivery_cost : delivery_cost, 
         total : total, 
         notes : notes, 
         qty_actual : qty_actual, 
         active : active 
        }; 
        saveTaskSupplies(taskSupply); 
        console.log(taskSupply); 
       } 
      }); 
     } 
    }); 
} 

function saveTaskSupplies(taskSupply) { 
    $.ajax({ 
     type : "POST", 
     url : "<?php echo base_url(); ?>" + "mgmt/project/saveTaskSupplies", 
     data : taskSupply, 
     dataType : "json", 
     cache : "false", 
     success : function(data) { 
      ++processedTaskSupplies; 

      // All supplies have been processed 
      if (processedTaskSupplies == totalTaskSupplies) { 
       // Do something 
      } 
     } 
    }); 
} 
+0

Das funktioniert, außer dass ich die Länge aller tr erhalten musste, die einen Wert in der Gesamtspalte in einer Eingabe namens 'comprectedCost' haben. Also habe ich das Inkrement in jeder anderen Schleife durchlaufen. Gibt es hier etwas Besseres als das, was ich verändert habe? 'trs.each (function() {var checkCount = $ (this) .find ('eingabe [name =" calculatedCost "]'). val(); \t \t \t \t if (checkCount! = 'n/a') { \t \t \t \t \t // hinzufügen Anzahl der Lieferungen für aktuelle Aufgabe Gesamt Aufgabe liefert \t \t \t \t ++ totalTaskSupplies; \t \t \t} \t \t}); \t ' – user1881482

+0

Theoretisch, da Sie die Summe in jeder" Iteration "addieren und Sie sofort die entsprechende Ajax Anfrage auslösen, wird es eine Chance geben, dass' if (processedTaskSupplies == totalTaskSupplies) 'eine nicht vollständig berechnet 'totalTaskSupplies' und führen zu einer früheren Weiterleitung, wenn noch keine Ajax-Anfrage ausgelöst wurde. –

+0

Ok .. das macht Sinn. Also habe ich die trs.length-Zählung außerhalb der Schleife verschoben, indem ich das gesamte Dokument für tr mit einer Eingabe mit einer Klasse von calculatedCost betrachtet habe und die Gesamtanzahl da draußen gefunden habe, die nicht gleich n/a war. Am Anfang der Klickfunktion 'var trsFilter = $ ('input.calculatedCost') filter (function() {return this.value! = 'N/a'}); \t \t totalTaskSupplies + = trsFilter.length; ' – user1881482

0

In Bezug auf die erste Frage, durch das Studium Ihres Codes konnte ich nicht den Grund dafür sehen. Sie führen nur die saveTaskSupplies() aus, wenn saveTasks() erfolgreich ausgeführt wurde, also sollte die task_id bereits erstellt werden.

Allerdings würde ich von einem anderen möglichen Problem von Ihrem Backend denkt, in Ihrer Funktion Ajax success in saveTasks(), übernehmen Sie die PHP-Skript immer erfolgreich auszuführen und die task_id zurückzukehren. Wäre es möglich, dass Ihr PHP-Skript ein Problem hat und die task_id nicht in einer Instanz erstellt wird?

Für die zweite Frage gibt es ein paar Ansätze, wie @Seth vorschlagen Sie jQuery.when verwenden können, oder Sie können einen globalen Zähler erstellen, um zu verfolgen, ob der saveTaskSupplies() der letzte ist. Beachten Sie, dass Sie die Gesamtlänge von Trs vor dem Abfeuern der Ajax-Anfrage berechnen sollten, sonst haben Sie möglicherweise eine Chance, eine nicht gut berechnete Summe zu haben und umleiten, bevor alle Aufgaben erledigt sind. Wenn es das letzte ist, wird es nach erfolgreichem Ajax-Aufruf umgeleitet.

// create a global counter 
var counter = 0, 
    trl = 0; 
$(document).on("click", "#submitTasks", function(e) { 
    ... 
    var trList = []; 
    tasks.each(function() { 
     // calculate the length of total task before actually firing the Ajax Request 
     var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr'); 
     // keep a copy of the trs so the next each loop does not have to find it again 
     trList.push(trs); 
     trl += trs.length; 
    }); 
    tasks.each(function() { 
     // get the trs of current iteration we have found in last loop 
     var trs = trList.shift(); 
     ... 
     saveTasks(task, trs, project_id); 
    }); 
}); 

function saveTasks(task, trs, project_id) { 
    $.ajax({ 
     ... 
     success : function(data) { 
      trs.each(function() { 
       ... 
       saveTaskSupplies(taskSupply); 
      } 
     } 
    }); 
} 

function saveTaskSupplies(taskSupply) { 
    $.ajax({ 
     ... 
     success : function(data) { 
      // check if the counter exceed the length of trs 
      if (++counter == trl) { 
       location.href = 'place you want to go'; 
      } 
     } 
    }); 
} 

Auf der anderen Seite, für Ihre Aufgabe würde ich vorschlagen, auch die Verantwortung der Dateneinfügung zu PHP Backend-Verschiebung, so alles, was Sie tun müssen, ist die Aufgabe, Informationen und die Aufgabe liefert sofort zu einem einzigen passieren PHP-Skript. Dieser Ansatz ermöglicht die Verwendung von Transaction, um sicherzustellen, dass alle Dateneinfügungen erfolgreich sind oder andernfalls alle fehlschlagen.

+0

Ich gebe das eine Chance ... Ich dachte, dass ich vielleicht alle Daten in einem Objekt weitergeben und es in PHP sortieren muss. Ich werde versuchen, die Gegenmethode hinzuzufügen und zu sehen, ob das Dinge für mich erleuchtet. Ich glaube, dass Sie Recht haben, und möglicherweise greift das Javascript nicht alle Daten auf, die es jedes Mal braucht. Senden Sie ein Objekt schneller als mehrere Ajax-Anfragen, würden Sie das wissen? – user1881482

+0

Es ist wichtig zu beachten, dass beide Methoden, Senden mehrere Insertion Anfrage und Single-Insertion-Anfrage beide arbeitsfähige Ansätze sind. Wenn Sie jedoch die Einfügung in PHP verschieben, profitieren Sie von der Transaktionstransaktion. Und bezüglich der Geschwindigkeit glaube ich, dass das Senden eines Objekts schneller ist, da es aus der Sicht des Netzwerks weniger Overhead verursacht, aber dass die Leistungsverbesserung in den meisten Situationen ziemlich vernachlässigbar ist. –

+0

Würde diese Umleitung nach der gesamten Lieferung in ** einer ** Aufgabe nicht bearbeitet? Es wird nicht überprüft, ob alle Aufgaben ebenfalls ausgeführt wurden. – cyberbit

3

Dieser Code für verschachtelte Schleife Ajax-Funktion wartet, ruft ihre Versprechen zu beenden, dann gehen ..

var allPromises; 

$(document).on("click", "#submitTasks", function(e) { 
    //... 
    var tasks = $('#tasks').find('.box'); 

    allPromises = []; 

    tasks.each(function() { 
     //.. somehow getTask 
     var req = saveTasks(task, trs, project_id); 
     allPromises.push(req); 
    }); 

    $.when.apply(null, allPromises).done(function(){ 
     // Do your things here, 
     // All save functions have done. 
    }); 
}); 

function saveTasks(task, trs, project_id) { 
    return $.ajax({ 
     // ,,, your codes 
     success : function(data) { 
      // ... 
      trs.each(function() { 
       // ... Somehow get taskSupply 
       var req = saveTaskSupplies(taskSupply); 
       allPromises.push(req); 
      } 
     } 
    }); 
} 

function saveTaskSupplies(taskSupply) { 
    return $.ajax({ 
     // ... bla bla bla 
     success : function(data) { 
      // Whatever.. 
     } 
    }); 
} 
+1

Ich werde versuchen, dies auch zu implementieren. Ich mag die obige Gegenidee, und es funktioniert, aber dieser Ansatz lehrt mich neue Dinge über JS – user1881482

Verwandte Themen