javascript - 如何更新indexeddb而不是覆盖所有数据?

标签 javascript indexeddb

我真的很喜欢indexeddb的这种非常简单的使用,但我试图弄清楚如何进行更新。

我已经看到 .put 应该适用于这个,但是当我尝试这个时,它只会覆盖 id 12345 的所有数据。我错过了什么?

这是我在下面使用的:

store.put({id: 12345, name: {first: "John", last: "Doe"}, 年龄: 42});

store.put({id: 12345, name: {first: "somethingelse"}, 年龄: 42});

完整代码:

      var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;

      // Open (or create) the database
      var open = indexedDB.open("MyDatabase", 1);

      // Create the schema
      open.onupgradeneeded = function() {
          var db = open.result;
          var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
          var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
      };

      open.onsuccess = function() {
          // Start a new transaction
          var db = open.result;
          var tx = db.transaction("MyObjectStore", "readwrite");
          var store = tx.objectStore("MyObjectStore");
          var index = store.index("NameIndex");

          // Add some data
          store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});
          store.put({id: 12345, name: {first: "somethingelse"}, age: 42});

          // Query the data
          var custInfo = store.get(12345);

          custInfo.onsuccess = function() {
              alert("ID " + custInfo.result.id + " age " +custInfo.result.age + " name " + custInfo.result.name.first+ custInfo.result.name.last);  // => "John"
              // alert(getJohn.result.name.first);  // => "John"
          };

          // Close the db when the transaction is done
          tx.oncomplete = function() {
              db.close();
          };
      }

最佳答案

如果我正确理解你的问题,那么我会指出调用 put 并不等同于 SQL update。您不能使用单个请求仅替换对象存储中对象的某些属性。将新对象放入存储时,如果具有相同键路径(id)的另一个对象已存在,则该现有对象将被完全替换。 indexedDB 不会一次修改存储中的现有对象,一次修改一个属性,而是用新对象完全替换旧对象。

如果您只想替换对象的某些属性,请使用两个请求。一个请求获取存储中的现有对象,第二个请求存储修改后的对象。在 get 和 put 之间,对对象进行更改。

类似这样的伪代码:

function updateSomeProps(db, id) {
  var tx = db.transaction(...);
  tx.oncomplete = _ => {
    console.log('finished updating object with id', id);
  };

  var store = tx.objectStore(...);
  var getRequest = store.get(id);
  getRequest.onsuccess = _ => {
     var obj = getRequest.result;
     if(!obj) {
       console.log('no matching object for id, canceling update', id);
       return;
     }

     console.log('loaded object to modify', obj);

     // make some changes to the properties of the object loaded 
     // in memory
     obj.age = 42;
     obj.firstname = 'asdf';
     delete obj.lastname;

     // now store the new object in place of the old object
     console.log('storing new object in place of old', obj);
     store.put(obj);
  };
}

function connectAndChangeStuff(id) {
  var openRequest = indexedDB.open(...);
  openRequest.onsuccess = _ => {
    var db = openRequest.result;
    updateSomeProps(db, 12345);
    db.close(); // optional
  };
}

关于javascript - 如何更新indexeddb而不是覆盖所有数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49846187/

相关文章:

javascript - setState() 不触发重新渲染

javascript - 如何使用 idbKeyval 获取我的 IndexedDB val 的 key ?

javascript - 本地数据库 API - 已弃用 有什么替代方案?

javascript - 将数据存储在 IndexedDB 中

javascript - 如何在 native react 中在控制台中显示整个对象

javascript - 如何解决 - 等待而不是等待

javascript - 确定 Promises.all 中哪个 Promise 最慢

javascript - 是否可以连接 KML 图层以在一个复选框(Google map )中显示它们?

google-chrome - 在 IndexedDB 和文件系统之间本地存储 chrome 应用程序数据的最佳选择是什么?

uiwebview - iOS 8是否通过UIWebView支持IndexedDB?