IndexedDB:修改对象存储中预先存在的对象

IndexedDB: Modifying pre-existing objects in an object store

我正在努力思考 IndexedDB

我创建了一个对象存储,它使用 key-generator 没有键路径。

var objectStore = db.createObjectStore("domains", {autoIncrement: true });
objectStore.createIndex("domain", "domain", { unique: true, multiEntry: true });

为了访问我的记录,我创建了一个 index 来引用我的对象存储。索引的关键路径是我记录的domain 属性。

这是我的对象存储中的一条记录的示例:

{ domain: ["stackexchange",
           "Whosebug",
           "superuser",
           "askubuntu",
           "serverfault"], 

  bold          : ["<strong>",1], 
  italic        : ["<em>",1],
  strikethrough : ["<del>",1],
  superscript   : ["<sup>",1],
  subscript     : ["<sub>",1],
  heading1      : ["<h1>",1],
  heading2      : ["<h2>",1],
  heading3      : ["<h3>",1],
  blockquote    : ["<blockquote>",1],
  code          : ["<code>",1],
  newline       : ["<br>",2],
  horizontal    : ["<hr>",2]
},

domain 属性 中出现的每个条目保证在由我的对象存储的每条记录中每个域键值的并集组成的集合中是唯一的。 IE。在我的对象存储库中的其他任何地方都找不到这些域中的任何一个。

我需要让用户编辑对象存储中的对象。提供单个域,我可以像这样检索关联的对象:

var DBOpenRequest= window.indexedDB.open(db_name, db_version);
DBOpenRequest.onsuccess= function(event){   
    var db= DBOpenRequest.result;
    var domains=db.transaction('domains', 'readwrite').objectStore('domains');

    var query = domains.index("domain").get("Whosebug");   
};

现在,这是我感到困惑的部分。一旦用户根据需要将他们想要的属性更改为 edit/added 新属性,我需要通过将上面检索到的对象替换为用户创建的新对象来保存他们的更改。 (或修改原始对象并保存更改)。

我想我需要使用 IDBObjectStore.put() 来做这个。

put()方法有两个参数,一个是必须的,一个是可选的:

value
    The value to be stored.
key
    The key to use to identify the record. If unspecified, it results to null.

对于您使用内联键的实例,第二个参数可能是可选的。我正在使用由密钥生成器生成的外联密钥。

如何获取通过我的索引检索到的对象的(自动生成的、离线的)键,以便我可以与我想要修改该预先存在的对象的对象存储通信而不是创建一个新的?

还有其他方法可以解决这个问题吗?

以下是来自 IndexedDB specs for indexes 的文字。

Each index also has a unique flag. When this flag is set to true, the index enforces that no two records in the index has the same key. If a record in the index's referenced object store is attempted to be inserted or modified such that evaluating the index's key path on the records new value yields a result which already exists in the index, then the attempted modification to the object store fails.

因此,如果在 属性 上创建了唯一索引,则无法使用 "put()"因此,您可以创建一个主键,即在创建对象存储时使用 keyPath

var objectStore = db.createObjectStore("domains", {keyPath: "domain"});

检查以下 2 个 URL,这将帮助您更深入地了解如果存在唯一索引则无法执行更新。

致未来的读者。作为使用键路径的替代方法:

而不是使用 IDBObjectStore.put() you can iterate over the objects in the object store with IDBObjectStore.openCursor()

一旦你找到你要找的对象,你可以使用: