我目前已经设置了一个AJAX到PHP的一组函数来处理页面上的许多项目。基本上,代码将一系列任务插入到数据库中,然后根据新创建的任务ID将数据插入数据库。然而,它在90%的时间都有效。有时似乎不会首先创建任务ID,因为它不允许耗材使用这些ID插入数据库。有没有办法确保插入任务,然后为该ID插入所有耗材,然后移动到下一个。最后,当一切都完成后,我想重定向到一个新的页面,我再次将它放在供应部分的最后一次成功调用中,但它会在第一个循环上重定向。此过程通常会生成大约5个任务,每个任务有12个供应。我正在阅读有关$.when
循环但无法使其工作的内容。注意:在测试之后,ajax调用正确提交,其中一些字段是空的,并且数据库出现问题。所以下面的计数器方法有效。
$(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 :(得分:3)
此代码将等待嵌套循环ajax函数调用以完成其承诺,然后继续..
state.go
答案 1 :(得分:2)
这是使用您提供的代码的直接解决方案。基本概念是在处理供应品时增加计数器。一旦计数器达到耗材总数,就会运行一个程序。请参阅评论。
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
}
}
});
}
答案 2 :(得分:0)
关于第一个问题,通过研究你的代码,我看不出它的原因。只有saveTaskSupplies()
成功执行后才能执行saveTasks()
,因此应该已经创建了task_id
。
但是,在success
的Ajax saveTasks()
函数中,我会考虑后端的另一个可能的问题,假设PHP脚本总是成功执行并返回task_id
。你的PHP脚本是否有可能出现问题而某些实例中没有创建task_id
?
对于第二个问题,有一些方法,因为@Seth建议您可以使用jQuery.when,或者您可以创建一个全局计数器来跟踪saveTaskSupplies()
是否是最后一个。请注意,您应该在触发Ajax请求之前计算trs的总长度,否则,在完成所有任务之前,您可能有一个计算不佳的总数并重定向。如果它是最后一个,它将在成功调用Ajax后重定向。
// 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';
}
}
});
}
另一方面,对于您的任务,我还建议将数据插入的责任转移到PHP后端,因此您需要做的就是将任务信息和任务供应一次性传递给单个PHP脚本。这种方法允许使用Transaction来确保所有数据插入成功或者全部都应该失败。
答案 3 :(得分:0)
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).always(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..
}
});
}