我有一个页面正在向cfc发布JSON,并返回成功/失败消息。构建JSON的数组包含已更新的输入字段的ID。我正在更改元素的背景颜色以提醒用户进行了更新,但是当用户在不离开页面的情况下发布更多更改时会出现问题。该数组仍包含上一篇文章中的数据,无论我尝试清除数组的内容或位置,后台的更改都会停止工作。
以下是代码:
$("input").change(function(){
theArray.push({
'id':$(this).attr('id'),
'value':$(this).val()
});
});
$("#edit_button").click(function(){
if(theArray.length >0){
theArray.push({
//some processing information to the cfc
});
theJson = JSON.stringify(theArray);
$.post("CFCs/fund_profile.cfc",
{
method:"updateProfile",
data:theJson
},
function(data){
if(data.HASERROR == 1){
$("#messageDiv").empty().html(data.MESSAGE);
}
else{
$("#messageDiv").empty().html(data.MESSAGE);
theArray.pop();//removing the cfc processing information
for(var i = 0; i <= theArray.length; i++){
var $el = $("#" = theArray[i].id).parent().parent().css('background','red');
setTimeout(function(){
$el.css('background','');
$("#messageDiv").empty();
},5000);
}
}
},
"json");
//THIS IS WHERE THE PROBLEM LIES (I THINK)
//I HAVE TRIED THE FOLLOWING:
var arrayLen = theArray.length;
for(var j = 0;j <= arrayLen; j++){
theArray.pop();
}//DOESN'T WORK
theArray.length = 0;
//DOESN'T WORK
for(var j = 0;j <= arrayLen; j++){
theArray.shift();
}//DOESN'T WORK
}
});
如果我删除代码以清除数组,则会发生背景更改,但数组永远不会丢失该元素,并且始终会将该元素显示为已更新。如果我保留它,背景变化根本不会发生。
我确信这是一件我想念的简单事,但我对此感到沮丧。
有什么想法吗?
答案 0 :(得分:2)
根据您发布的代码的布局(这不完全有效,所以我担心它不是您正在使用的实际代码),您正在处理帖子 - 在错误的地方调用AJAX的条件。它是$.post()
回调函数的外部,因此它不会以相同的顺序发生(或不保证会发生)。请记住,AJAX是异步,所以在回调函数之前正在发生指示哪些有效或无效的代码。
我建议尽可能使$.post()
中的回调函数保持自主。不要让它在JavaScript中与数组交互,而是让服务器在正在更新的元素的JSON响应中返回一个数组。然后回调函数可以自己愉快地与这些元素进行交互,并且在过渡期间产生的回调函数的其他实例不会妨碍它。
所以,基本上,你会在$.post()
回调之外保持数组的清除,所以它会在AJAX调用之后立即发生(并且可能在所有情况下都发生之前)它返回)。您将修改服务器端代码以返回受影响的ID。传递给回调函数的data
参数将包含这些ID,您可以使用它与CSS交互,而不是直接使用theArray
。
答案 1 :(得分:1)
在if / else语句后面的post语句中添加:
theArray = [];
这有效地使数组变空。无需循环播放。
另外,正如大卫所指出的,它必须在帖子的成功之内,而不是在它之后。
修改强>
你的for循环没有完全按照你的预期执行,setTimeout应该只影响最后一个元素。要解决此问题,请切换到$.each
,或在for循环内创建匿名函数。
for(var i = 0; i <= theArray.length; i++){
(function(i){
var $el = $("#" = theArray[i].id).parent().parent().css('background','red');
setTimeout(function(){
$el.css('background','');
$("#messageDiv").empty();
},5000);
})(i);
}
还有一个注意事项:
如果有人在第一组数据完成之前向服务器提交第二组数据,由于两种情况都使用相同的数组,事情可能会变得非常混乱。大卫很好地接触了他的回答。也许在点击事件中,您应该立即复制数组,然后清除原始数据,将其打开以供下次点击使用。
示例(可能正常,未经测试):
var theArray = [];
$("input").change(function() {
theArray.push({
'id': $(this).attr('id'),
'value': $(this).val()
});
});
$("#edit_button").click(function() {
var myArray = $.extend([], theArray, true); // get a copy of theArray
theArray = []; // empty theArray
if (myArray.length > 0) {
myArray.push({
//some processing information to the cfc
});
theJson = JSON.stringify(myArray);
$.post("CFCs/fund_profile.cfc", {
method: "updateProfile",
data: theJson
}, function(data) {
if (data.HASERROR == 1) {
$("#messageDiv").empty().html(data.MESSAGE);
}
else {
$("#messageDiv").empty().html(data.MESSAGE);
myArray.pop(); //removing the cfc processing information
var $el = $([]);
for (var i = 0; i <= myArray.length; i++) {
$el.add("#" = myArray[i].id);
}
$el = $el.parent().parent().css('background','red');
setTimeout(function(){
$el.css('background','');
$("#messageDiv").empty();
},5000);
}
}, "json");
}
});
编辑更新for last in last statement,应该更容易理解。