被索引的db delete困惑

时间:2012-12-22 15:46:25

标签: indexeddb delete-record

我的情景:

我有一个索引的数据库数据库页面,可以使用'删除文件检索多个文件(图片)。每张图片旁边的按钮。此外,每个图片旁边都有复选框,可以删除多个文件。删除文件'按钮调用' 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');
}

并且未成功:

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);
    }
};

对于为什么会发生这种情况的任何解释都将不胜感激。

5 个答案:

答案 0 :(得分:2)

在这里尝试代码后,我搜索了很长时间才得到答案,这有趣的是没有标记为解决方案。 Kyaw Tun的回答对我不起作用,但给了我一些想法。所以,尽管这是一个老线程,我会发布一个实际有效的完整解决方案,因为我在网上找不到解决这个相当常见问题的任何东西。我的解决方案是骨干,所以有一些上下文(主要是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 :(得分:0)

我没有看到任何明显错误的代码。一些建议:

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

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

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

  4. 编辑: key来自inputBttn.onclick的哪个位置?您确定massDelete正在将正确的值传递给deleteRecord吗?

答案 2 :(得分:0)

代码看起来没问题,但我会避免异步循环:

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");
  }
};

答案 3 :(得分:0)

根据MDN,对象存储只能在任何给定时间打开一个“读/写”事务。循环将尝试在彼此之上打开多个“读/写”事务,这可能导致失败。我假设Chrome中存在相同的限制。尽管您不需要继续重新开放交易,但Kyaw Tun的解决方案应该可以防止多次“读/写”交易。

Link To IDBTransaction MDN reference

答案 4 :(得分:0)

  1. 尝试删除多条记录时,请确保交易仍然有效。关于马歇尔的回答是正确的。
  2. 我在删除记录时遇到的另一个问题是,确定密钥是数字还是字符串。如果您使用了错误的 typeof key ,则该记录可能不会被删除。