我的场景:
我有一个索引db数据库页面,检索多个文件(图片)与"删除文件"按钮旁边的每个图片。此外,每个图片旁边都有复选框,用于删除多个文件。"删除文件"按钮调用"deleteRecord"函数,并将键传递给它…它可以很好地删除文件。但是,当批量删除按钮调用相同的'deleteRecord'函数进行批量删除并传递密钥时,没有文件被删除。'deleteRecord'遍历每个键并有一个onsuccess事件。然而,没有任何东西被删除?
deleteFile函数(适用于单个按钮):
function deleteRecord (id) {
console.log('inside deleteRecord. id: ' + id);
var transaction = db.transaction("patient", "readwrite");
var objectStore = transaction.objectStore("patient");
var request = objectStore.delete(id);
request.onsuccess = function(evt) {
console.log("It's gone!");
};
从
成功调用inputBttn.onclick = function () {
var prompt = 'Are you sure you want to delete this record?'
answer = confirm(prompt);
if (answer) {
deleteRecord(key);
console.log('Key = ' + key + ' Record Deleted');
}
and failed from:
function massDelete() {
console.log('inside massDelete');
var checkboxes = document.getElementsByName('c1');
var prompt = 'You are about to delete Multiple Records. Are you sure?'
var answer = confirm(prompt);
if (answer) {
console.log('Delete confirmed...starting mass delete');
for (var x = 0; x < checkboxes.length; x++) {
if (checkboxes[x].checked) {
var key = checkboxes[x].value;
console.log('checkbox value = ' + key);
deleteRecord (key);
}
};
如果能解释一下为什么会这样,我将不胜感激。
我搜索了很长一段时间,在这里尝试代码后得到答案,有趣的是没有标记为解决方案。觉吞的回答对我来说并不适用,但给了我一些想法。所以,尽管这是一个老话题,我还是会发布一个完整的解决方案,因为我在网上找不到任何解决这个常见问题的方法。我的解决方案是在主干,所以有一点上下文(主要是this
参考)很容易被忽略:
deleteFromDb: function(keys, callback) {
var _this = this,
request = indexedDB.open(_this.LOCAL_DB, _this.DB_VERSION);
request.onsuccess = function(event) {
var db = event.target.result,
tx = db.transaction([_this.URL_TABLE], "readwrite"),
store = tx.objectStore(_this.URL_TABLE),
recursiveDelete;
recursiveDelete = function(_index) {
var deleteRequest;
// base case
if (_index >= keys.length) {
callback();
return;
}
deleteRequest = store.delete(keys[_index]);
deleteRequest.onsuccess = function(event) {
recursiveDelete(_index + 1);
}
}
recursiveDelete(0);
}
}
我看不出代码有什么明显的错误。一些建议:
-
在deleteRecord中,为完成和中止事件的事务添加处理程序,看看哪个被触发:
transaction.onabort = function(e) { console.log("abort"); }; transaction.oncomplete = function(e) { console.log("complete"); };
-
deleteRecord缺少一个右括号,所以它可能不是您正在使用的实际代码。如果您有进一步的问题,请考虑将代码的简化版本上传到jsfiddle。
-
您在哪些浏览器上尝试过?他们都表现出同样的行为吗?
编辑:inputBttn.onclick
中的key
来自哪里?您确定massDelete
传递给deleteRecord
的值正确吗?
代码看起来不错,但是我将通过以下方式避免异步循环:
function deleteRecords (ids) {
var transaction = db.transaction("patient", "readwrite");
var objectStore = transaction.objectStore("patient");
var id = ids.shift();
var request = objectStore.delete(id);
request.onsuccess = function(evt) {
console.log(id + " deleted");
if (ids.length > 0) {
id = ids.shift();
objectStore.delete(id);
}
}
request.onerror = function(evt) {
console.log(id + " delete fail");
}
};
根据MDN,对象存储在任何给定时间只能有一个"读/写"事务打开。循环将试图打开多个"读/写"事务,这可能会导致失败。我认为同样的限制是存在于Chrome。Kyaw Tun的解决方案应该可以防止多个"读/写"交易,尽管你不需要一直重新打开交易。
链接到IDBTransaction MDN参考
- 当尝试删除多条记录时,确保事务保持活动。关于这一点,马歇尔的回答是正确的。
- 我在删除记录时面临的另一个问题是,确定键是数字还是字符串。如果您使用了错误的类型的键,记录可能不会被删除。