我有一个保存按钮,可以调用一个函数来打开一个带有两个按钮的模态对话框; “保存时间表”和“取消”。 “保存时间线”按钮调用页面需要重新加载的两个功能。我已经尝试了几种不同的方法来完成这项工作......
function genSaveTimelinesModal() {
$("#saveTimelineDialog").dialog({
resizable: false,
height: 250,
modal: true,
buttons: {
"Save timelines": function() {
editSavedTimelines();
saveTimelines();
$(this).dialog("close");
location.reload();
},
Cancel: function() {
$(this).dialog("close");
}
}
});
}
function genSaveTimelinesModal() {
$("#saveTimelineDialog").dialog({
resizable: false,
height: 250,
modal: true,
buttons: {
"Save timelines": function() {
editSavedTimelines(saveTimelines());
location.reload();
},
Cancel: function() {
$(this).dialog("close");
}
}
});
}
function genSaveTimelinesModal() {
$("#saveTimelineDialog").dialog({
resizable: false,
height: 250,
modal: true,
buttons: {
"Save timelines": function() {
$.when(editSavedTimelines(), saveTimelines()).do(location.reload());
},
Cancel: function() {
$(this).dialog("close");
}
}
});
}
在所有三次尝试中,我的问题出现在单击“保存时间线”按钮时...页面重新加载并且没有运行任何功能。当我从每个示例中拉出location.reload()调用时,函数按我想要的那样运行。
是否有办法在功能完成后重新加载页面?
供参考,以下是我正在调用的函数:
function saveTimelines() {
console.log("start save");
for (i=1; i < timelineIndex + 1; i++) {
var dow = startdow;
var clientValue = $("#clientNameSelect" + i).val();
var projectValue = $("#projectSelect" + i).val();
var taskValue = $("#taskSelect" + i).val();
var billingValue = $("#billingSelect" + i).val();
var activityValue = $("#activitySelect" + i).val();
var stateValue = $("#states" + i).val();
var sundayValue = $("#sun" + i).val();
var mondayValue = $("#mon" + i).val();
var tuesdayValue = $("#tue" + i).val();
var wednesdayValue = $("#wed" + i).val();
var thursdayValue = $("#thu" + i).val();
var fridayValue = $("#fri" + i).val();
var saturdayValue = $("#sat" + i).val();
$.ajax({
type: "GET",
url:"biqqyzqyr?act=API_DoQuery&query={'6'.EX.'" + projectValue + "'}AND{'16'.TV.'" + currUserEmail + "'}&clist=3&includeRids=1&fmt=structured",
dataType: "xml",
success: function (xml) {
$(xml).find("record").each(function () {
var resourceMap = new Array();
$(this).children().each(function () {
var name = $(this).attr("id");
var value = $(this).text();
resourceMap[name] = value;
});
resourceRecords.push(resourceMap);
});
console.log("hi");
var resourceRId = '3';
for (var j = 0; j < resourceRecords.length; j++) {
resourceOptions = resourceRecords[j][resourceRId];
console.log(resourceOptions);
}
$.ajax({
type: "GET",
url: "biha4iayz?act=API_AddRecord&_fid_12=" + dow + "&_fid_36=" + clientValue + "&_fid_9=" + projectValue + "&_fid_7=" + taskValue + "&_fid_10=" + billingValue + "&_fid_15=" + activityValue + "&_fid_11=" + stateValue + "&_fid_13=" + sundayValue + "&_fid_57=" + mondayValue + "&_fid_58=" + tuesdayValue + "&_fid_59=" + wednesdayValue + "&_fid_60=" + thursdayValue + "&_fid_61=" + fridayValue + "&_fid_62=" + saturdayValue + "&_fid_17=" + resourceOptions,
dataType: "xml",
success: function () {
console.log(i+ "new")
},
fail: loadFail
});
},
fail: loadFail
});
}
alert(timelineIndex+savedTimelineIndex+" timelines have been saved to the system...");
}
function editSavedTimelines(callback) {
console.log("start edit");
for (j=1; j < savedTimelineIndex + 1; j++) {
var dow = startdow;
var savedRId = $("#recordsaved" + j).val();
var sundayValue = $("#sunsaved" + j).val();
var mondayValue = $("#monsaved" + j).val();
var tuesdayValue = $("#tuesaved" + j).val();
var wednesdayValue = $("#wedsaved" + j).val();
var thursdayValue = $("#thusaved" + j).val();
var fridayValue = $("#frisaved" + j).val();
var saturdayValue = $("#satsaved" + j).val();
console.log(savedRId);
$.ajax({
type: "GET",
url: "biha4iayz?act=API_EditRecord&rid=" + savedRId + "&_fid_13=" + sundayValue + "&_fid_57=" + mondayValue + "&_fid_58=" + tuesdayValue + "&_fid_59=" + wednesdayValue + "&_fid_60=" + thursdayValue + "&_fid_61=" + fridayValue + "&_fid_62=" + saturdayValue,
dataType: "xml",
success: function () {
},
fail: loadFail
});
}
}
答案 0 :(得分:2)
这对你有用。它为for循环中的ajax调用使用了Deferred对象数组,并且在所有这些对象完成时有一个最终的延迟对象。外部函数侦听那些延迟对象的完成。请注意,我已经剪切了许多不相关的代码,并且从成功回调更改为.done()
以进行ajax调用。
function genSaveTimelinesModal() {
$("#saveTimelineDialog").dialog({
resizable: false,
height: 250,
modal: true,
buttons: {
"Save timelines": function() {
$.when(editSavedTimelines(), saveTimelines()).done(function() {
location.reload();
});
},
Cancel: function() {
$(this).dialog("close");
}
}
});
}
function saveTimelines() {
var finalDef = $.Deferred();
var defs = [];
for (i=1; i < timelineIndex + 1; i++) {
var def = $.Deferred();
defs.push(def);
$.ajax({...}).done(function(xml) {
$.ajax({...}).done(function() {
def.resolve(true);
});
});
}
$.when.apply(null, defs).done(function() {
finalDef.resolve();
});
return finalDef.promise();
}
function editSavedTimelines() {
var finalDef = $.Deferred();
var defs = [];
for (j=1; j < savedTimelineIndex + 1; j++) {
var def = $.Deferred();
defs.push(def);
$.ajax({...}).done(function() {
def.resolve(true);
});
}
$.when.apply(null, defs).done(function() {
finalDef.resolve(true);
});
return finalDef.promise();
}
答案 1 :(得分:2)
使用when
的问题是你的两个函数都没有返回任何内容。你的电话基本上就是这个:
$.when(undefined, undefined)
你的saveTimelines
函数是一个更复杂的函数,因为你在第一个函数的回调中进行了第二个ajax调用。更糟糕的是,这些ajax调用处于循环中。 因此,在完成循环的每次迭代的内部ajax
调用之前,您的函数不会“完整”。
我强烈建议尝试完全重新设计它以简化操作。如果您可以消除循环以及嵌套的ajax调用,这将更容易。
话虽如此,让我们看看如何克服这个问题。首先要处理内部ajax调用的问题,你可以通过创建自己的延迟对象来解决这个问题。这样的事情(暂时忽略循环):
function saveOneTimeline(/* any params here, such as i */) {
// create a deferred object which will be returned by this function and resolved once all calls are complete
var def = $.Deferred();
/* ... */
$.ajax({
/* ... */
success: function (xml) {
/* ... */
$.ajax({
/* ... */
success: function () {
// we are done, resolve the deferred object
def.resolve();
}
});
}
});
// return the deferred object so that the calling code can attach callbacks/use when
return def;
}
最后,我们可以在循环中调用前面的方法,将返回的延迟对象放入一个数组中,然后使用when
返回一个只有在所有延迟解析后才能解析的promise。它看起来像这样:
function saveTimelines() {
// an array to store all of the deferreds
var defs = [];
for (i=1; i < timelineIndex + 1; i++) {
defs.push(saveOneTimeline(i));
}
// call when on the array of deferred objects and return the resulting promise object
return $.when.apply($, defs);
}
由于您没有嵌套的ajax调用,因此editSavedTimelines
稍微复杂一些。但是,你仍然有一个循环。可以使用非常类似的方法,除了辅助函数可以直接返回ajax
调用返回的对象。
正如你所看到的,这一切都非常复杂。相反,尝试消除一些复杂性以避免不得不达到这些长度可能是一个更好的主意。也许如果你可以在循环中进行一次批量ajax调用而不是多次调用,那么允许后端代码处理分离。