我在一个进行Ajax调用的复选框上有一个jQuery更改事件,然后突出显示该复选框所属的表行。当Ajax调用报告错误时,我遇到了问题 - 在这种情况下,我想要反转复选框点击(我正在使用that.prop("checked", !that.prop("checked"))
这样做)。然而,正在发生的是它进入调用change事件的无限循环。正如你所看到的,为了阻止这种行为,我试图设置一个名为ajaxInProgress的变量,但它似乎并没有像我希望的那样工作。任何人都可以提供替代方法或发现错误吗?我不确定我重置复选框的方式是必要的 - 是否可以重置复选框并仍然阻止更改事件开始?
var ajaxInProgress = false; //add this to stop recursive calls when errors occur
jQuery(document).ready(function() {
jQuery(".cc").change(function (e) {
if (ajaxInProgress) return;
var mode = "remove"
if (jQuery(this).attr("checked")) {
mode = "add"
}
//grab the application ID from the checkbox ID
var thisApp = this.id.substr(3);
var that = jQuery(this);
ajaxInProgress = true;
jQuery.get("/particular/edit-ajax", { application_id: thisApp,
party_id: 1920,
party_rel_id: 21,
mode: mode} , function(response) {
if (response == 0) {
that.closest('tr').removeClass('even').removeClass('odd').addClass('highlight');//highlight the tr
} else {
e.preventDefault();
that.prop("checked", !that.prop("checked")); //reset the checkbox if there was an error
alert("Please contact support - couldn't update database for application "+thisApp+". Response was: "+response);
}
});
ajaxInProgress = false;
});
});
答案 0 :(得分:2)
这一切看起来都非常复杂,我只会这样做:
(function($) {
$(function() {
function sendAjax(e) {
var data = {
application_id: this.id.substr(3),
party_id: 1920,
party_rel_id: 21,
mode: this.checked?'add':'remove',
},
that=this;
$.ajax({
type: 'GET',
data: data
}).done(function() {
$(that).closest('tr').removeClass('even odd').addClass('highlight');
}).fail(function(response) {
e.preventDefault();
that.checked = !that.checked;
alert("Please contact support - couldn't update database for application "+that.id.substr(3)+". Response was: "+response);
}).always(function() {
$(".cc").one('change', sendAjax);
});
}
$(".cc").one('change', sendAjax);
});
})(jQuery);
答案 1 :(得分:1)
可能是因为您ajaxInProgress = false;
之后jQuery.get
。在您从ajax请求中获取任何内容之前,这会将其设置为false
。将该行移至回调内部:
jQuery.get("/particular/edit-ajax",
{
application_id: thisApp,
party_id: 1920,
party_rel_id: 21,
mode: mode
},
function(response) {
ajaxInProgress = false;
if (response == 0) {
that.closest('tr').removeClass('even').removeClass('odd').addClass('highlight');//highlight the tr
} else {
e.preventDefault();
that.prop("checked", !that.prop("checked")); //reset the checkbox if there was an error
alert("Please contact support - couldn't update database for application "+thisApp+". Response was: "+response);
}
}
);
小提琴:http://jsfiddle.net/gromer/BgNfR/
我的小提琴正在使用window.setTimeout
来模拟ajax调用。我认为我的解决方案不起作用,但这是因为我最初使用window.setInterval
所以看起来就像是一遍又一遍地调用它,它就是这样,只是没有模拟我应该是ajax请求。
答案 2 :(得分:0)
使用“正在处理”变量为真:
var ajaxInProgress = false, handlingInProgress = false; //add this to stop recursive calls when errors occur
jQuery(document).ready(function() {
jQuery(".cc").change(function (e) {
if (handlingInProgress) return;
if (ajaxInProgress) return;
var mode = "remove"
if (jQuery(this).attr("checked")) {
mode = "add"
}
//grab the application ID from the checkbox ID
var thisApp = this.id.substr(3);
var that = jQuery(this);
ajaxInProgress = true;
jQuery.get("/particular/edit-ajax", { application_id: thisApp,
party_id: 1920,
party_rel_id: 21,
mode: mode} , function(response) {
if (response == 0) {
that.closest('tr').removeClass('even').removeClass('odd').addClass('highlight');//highlight the tr
} else {
e.preventDefault();
that.prop("checked", !that.prop("checked")); //reset the checkbox if there was an error
handlingInProgress = true; // Please see not below
alert("Please contact support - couldn't update database for application "+thisApp+". Response was: "+response);
}
});
ajaxInProgress = false;
handlingInProgress = false; //
});
});
当您更改复选框时,事件再次触发,但因为handlingInProgress
设置为true,它会立即从处理程序中断开。