我有一个使用在列中组织的项目(div元素)的Web应用程序,并且在跟踪用户当前选择的项目时遇到问题。
我目前通过保留一个包含所选项目ID的内部变量(例如item_id
)来实现。删除当前选定的项目将选择直接位于已删除项目下方的项目。在客户端删除项目时,它会向服务器发送AJAX调用。此调用发送要删除的项目的ID。如果呼叫成功完成,则会更新item_id
。我正在使用异步AJAX调用。当用户反复(并且非常快!)删除项目时,item_id
有时会不同步。我想阻止这种行为。
以下是我认为这个问题是如何发生的。假设我列出了3个项目['apple','banana','coconut']
,目前已选择'apple'
。为了可视化,它看起来像这样。 “{}”表示所选项目,“X”是用于删除项目的按钮。
+---------+---+
| {apple} | X |
| banana | X |
| coconut | X |
+---------+---+
然后,可能会发生以下情况。
'apple'
,并启动了删除'apple'
的AJAX调用。'banana'
,并启动了删除'banana'
的AJAX调用。item_id
现在拥有'coconut'
。'banana'
。此时,列表中剩下的唯一项目是'coconut'
,但item_id
保留不再存在的'banana'
ID。这对我来说是一个问题。
由于这些调用是异步的,因此它们之间存在竞争。我使用插件来序列化使用队列的AJAX调用,但似乎仍有一个竞争条件,调用首先进入队列。
我应该如何实现这一点,以便item_id
永远不会失去同步并正确指向列表中的选定项目?
编辑:以下是我用来删除项目的简化代码。
function deleteItem (item_id) {
$.ajax({
type: 'POST',
url: '/update.php',
data : {
item_id : item_id
}
})
.done(function () {
var deleted_item = $('#' + item_id);
var nearest_list = deleted_item.next();
// use the item below if it exists, otherwise get it from above
nearest_item = nearest_item.length !== 0 ? nearest_item : deleted_item.prev();
deleted_item.remove();
if (nearest_item.length === 0) { // i.e. there are no more items in the list
doSomething();
} else if (item_id === selected_item_id) { // you deleted a selected item
var nearest_item_id = nearest_item.attr('id');
$('#' + nearest_item_id).addClass('selected-item');
selected_item_id = nearest_item_id;
loadItem(nearest_item_id);
}
})
.fail(function (err,textStatus,errorThrown) {
handleError(err,errorThrown);
}
}
答案 0 :(得分:1)
您描述的内容称为溢出。用户点击的速度比将删除信息传递给服务器的速度快,“多个元素”不适合只能容纳一个元素的容器,因此行为变得不明确(并且不合需要)。
解决方案:不要使用单个变量来跟踪删除,请使用列表。
deletion
队列,禁用页面上的元素,使其不再被点击(看起来变灰等)。deletion
队列的pop元素,并将其添加到pending
qeueu pending
队列中的元素并将其从页面中删除。所以你的想法很好,唯一的问题是当你真正需要一个堆栈/队列/数组/列表/ whathaveyou时,你不小心使用了一个var
。