【问题标题】:How do I read an objects key in an indexeddb autoincrement objectstore, given an index给定索引,如何读取 indexeddb 自动增量对象存储中的对象键
【发布时间】:2014-03-21 15:19:29
【问题描述】:

代码形式的这个问题,我可以使用.put(doc, key)覆盖对象,但我不知道如何读取它的密钥

// After writing doc1 to an autoincrement
// objectStore, I want to overwrite it 
// later, I only know its index 
// (not its key)

var docs = [
  {'a':'doc1', 'my_index': 'anindex'},
  {'a':'doc2', 'my_index': 'anindex'}
];

indexedDB.deleteDatabase('foo').onsuccess = function () { 

  var idb;
  var req = indexedDB.open('foo');

  function writeDocs(docs) {

    if (!docs.length) { 
      console.log('done writing');
      return;
    }

    var txn = idb.transaction(['some_store_name'], 'readwrite');
    var doc = docs.shift();
    console.log('writing', doc);

    var get = txn.objectStore('some_store_name').index('my_index')
      .get(doc.my_index);

    get.onsuccess = function(e) { 

      var key = null;

      if (e.target.result) { 
        // If there is a result here, I want to overwrite it
        // to do that I need its key, cant find it here?    
        console.log(e.target.result);
      }

      var dataReq = txn.objectStore('some_store_name').put(doc);

      dataReq.onsuccess = function (e) {
        console.log('wroted', e.target.result);
        writeDocs(docs);
      }

      dataReq.onerror = function () { 
        console.log('it broke');
        writeDocs(txn, docs);
      }
    }
  };

  req.onupgradeneeded = function(e) {
    var db = e.target.result;
    db.createObjectStore('some_store_name', {autoIncrement : true})
      .createIndex('my_index', 'my_index', {unique: true});
  };

  req.onsuccess = function(e) { 
    idb = e.target.result;
    writeDocs(docs);
  };
}

【问题讨论】:

    标签: html indexeddb


    【解决方案1】:
      if (e.target.result) {
        // If there is a result here, I want to overwrite it
        // to do that I need its key, cant find it here?    
        console.log(e.target.result);
      }
    

    e.target.result其实是关键!但仅作为对putadd 的回应,而不是get。您可以使用此值来put() 将来的数据。

    没有行键,就像你有:objectstore.put(data, key)

    使用内联键,您只需 objectstore.put(data)

    更新:问题是您正在循环 writeDocs,但在您的第一个循环中,keynull,因此会引发错误。

    Here's a working example.

    第二次更新:看起来可能已经添加了一些代码,或者我之前错过了一些东西。除了我在上面标记的内容之外,您的索引是unique,并且您两次使用相同的my_index 值,因此第二个put() 出现错误。我在我的小提琴解决方案中通过使 my_index 每个页面加载唯一来避免这个问题。

    【讨论】:

    • 我没有.put结果的上下文,我只有索引,但我想出了答案,内联键将放在文档内
    • 添加了一个小提琴示例来帮助您前进。
    • key 始终为空,我从不使用它,是从另一次尝试中遗留下来的,没有对问题进行任何编辑,但我认为你误解了这个问题,我有索引,我需要关键
    • 对于你的例子,是的,在这种情况下我不能存储密钥,我只有索引
    • 您将根据要求在我的示例中的e.target.result 找到密钥。一个 put 总是产生一个键。
    【解决方案2】:

    已编辑:对此的简单解决方案是使用index.getKey(indexVal),切换到内联键也可以,但会导致迁移混乱。将db.createObjectStore('some_store_name', {autoIncrement : true}).createIndex('my_index', 'my_index', {unique: true}); 更改为db.createObjectStore('some_store_name', {keyPath: 'seq', autoIncrement : true}).createIndex('my_index', 'my_index', {unique: true});

    // After writing doc1 to an autoincrement
    // objectStore, I want to overwrite it 
    // later, I only know its index 
    // (not its key)
    
    var docs = [
      {'a':'doc1', 'my_index': 'anindex'},
      {'a':'doc2', 'my_index': 'anindex'}
    ];
    
    indexedDB.deleteDatabase('foo').onsuccess = function () { 
    
      var idb;
      var req = indexedDB.open('foo');
    
      function writeDocs(docs) {
    
        if (!docs.length) { 
          console.log('done writing');
          return;
        }
    
        var txn = idb.transaction(['some_store_name'], 'readwrite');
        var doc = docs.shift();
    
        var get = txn.objectStore('some_store_name').index('my_index')
          .get(doc.my_index);
    
        get.onsuccess = function(e) {
    
          if (e.target.result) { 
            doc.seq = e.target.result.seq;
          }
          var dataReq = txn.objectStore('some_store_name').put(doc);
    
          dataReq.onsuccess = function (e) {
            console.log('wroted', e.target.result);
            writeDocs(docs);
          }
    
          dataReq.onerror = function () { 
            console.log('it broke');
            writeDocs(txn, docs);
          }
        }
      };
    
      req.onupgradeneeded = function(e) {
        var db = e.target.result;
        db.createObjectStore('some_store_name', {keyPath: 'seq', autoIncrement : true})
          .createIndex('my_index', 'my_index', {unique: true});
      };
    
      req.onsuccess = function(e) { 
        idb = e.target.result;
        writeDocs(docs);
      };
    }
    

    【讨论】:

    • 这实际上不是你问题的核心。请参阅我的更新答案。
    • 例如,此代码仍应引发唯一性要求错误,因为 anindex 被两次用作唯一索引 my_index 的值
    • 它不会/不会抛出约束错误,因为我使用内联键覆盖现有条目 - codepen.io/anon/pen/zHhCx。我想在不指定内联键的情况下执行此操作,但是在给定单个唯一索引的情况下,我找不到如何找到引用的对象的键(也是问题的标题)
    猜你喜欢
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 2016-07-25
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多