Jquery DOM 在 .each() 迭代后不更新
我试图在每次迭代时跟踪更新,当每次完成时,我想以一种优雅的方式向用户显示摘要。我已经尝试了几乎所有方法调用来更新页面上的元素,但除非我在事件调用中的任何时候发出警报,否则它不会更新。
如果有人知道我可能缺少什么,我想看看它是如何完成的。非常感谢!
$('#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;
});
解决方案!!!
首先非常感谢所有人,特别是@SLaks!其次,http://james.padolsey.com/javascript/monitoring-dom-properties / 被认为是一个监视对象的小插件。
我所做的是将原始变量转换为本质上被监视的对象。使用上面的 jquery 插件,我观察了对象的条件:newVal == 0,其中 newVal 是eachCount 的新值。该手表每毫秒都会等待所有服务器响应以错误或成功的方式返回给我。完成后,我会显示一个关于所发生操作的漂亮的小摘要报告。
我不太确定这是否是最好的方法,但它在屏幕上看起来不错,而且我的眼睛看着它也不会太痛。以下是我的解决方案。稍后我将添加有关保持队列中剩余内容的活动记录更新的建议。所有这些代码主要是我添加的调试。
$('#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;
});
I am trying to keep track of updates as the each iterates and when the each is finished I would like to show a summary to the user in a graceful way. I have tried almost everything to a method call to update an element on the page but unless I fire off an alert at any point in the event call it will not update.
If anyone knows what I may be missing I would like to see how it is done. Big THANKS in advance!
$('#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!!!
First many thanks to all and specifically @SLaks! Second, http://james.padolsey.com/javascript/monitoring-dom-properties/ is credited for a small plugin to monitor an object.
What I did was convert my original variables to an object that was essentially watched. Using the jquery plugin from above I watched the object for a condition: newVal == 0, where newVal is the new value of the eachCount. That watch hit every millisecond waiting for all the server responses to come back to me with error or success. When finished I display a nice little summary report of the actions that happened.
I'm not too sure if this was the best way but it looks good on the screen and my eyes dont hurt too bad looking at it. Below is my solution. Later I will add in the suggestions for keeping an active record update of what is left in the queue. All that code was primarily the debugging that I was adding.
$('#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;
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题看起来可能
在于ajax函数内部调用成功和错误时需要调用This。
而且这确实不是最好的方法。实际上,您应该使用带有
keep-alive
的 ajax 连接,并在一个 POST 中发送数据,然后定期让 PHP 脚本以 JSON 格式发回最新状态:{ "countSuccess": "5 ", "countError", "0", "current": "5", "total": "10" }
然后当 current == Total 时你知道它已经完成,显示一个详细说明结果的信息 div。 :)The problem looks like it could lie in
This needs to be called when the success and error is called inside the ajax function.
Also this really isn't the best way of doing it. Really you should use a ajax connection with
keep-alive
and send the data in one POST then periodically have your PHP script send back the latest status in JSON format:{ "countSuccess": "5", "countError", "0", "current": "5", "total": "10" }
then when current == total you know it's complete, show an information div detailing the results. :)$.ajax
是一个立即返回的异步调用。在服务器回复后,稍后会调用
success
回调。因此,在
each
循环之后,尚未运行任何success
回调。$.ajax
is an asynchronous call which returns immediately.The
success
callback is called later, after the server replies.Therefore, after your
each
loop, none of thesuccess
callbacks have run yet.