索引数据库删除困惑



我的场景:

我有一个索引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);
    }   
}

我看不出代码有什么明显的错误。一些建议:

  1. 在deleteRecord中,为完成和中止事件的事务添加处理程序,看看哪个被触发:

    transaction.onabort = function(e) { console.log("abort"); };
    transaction.oncomplete = function(e) { console.log("complete"); };
    
  2. deleteRecord缺少一个右括号,所以它可能不是您正在使用的实际代码。如果您有进一步的问题,请考虑将代码的简化版本上传到jsfiddle。

  3. 您在哪些浏览器上尝试过?他们都表现出同样的行为吗?

编辑: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参考

  1. 当尝试删除多条记录时,确保事务保持活动。关于这一点,马歇尔的回答是正确的。
  2. 我在删除记录时面临的另一个问题是,确定键是数字还是字符串。如果您使用了错误的类型的键,记录可能不会被删除。

相关内容

  • 没有找到相关文章

最新更新