IndexedDB: изменение уже существующих объектов в хранилище объектов
Я пытаюсь обернуть голову вокруг IndexedDB.
Я создал хранилище объектов, которое использует генератор ключей без ключевого пути.
var objectStore = db.createObjectStore("domains", {autoIncrement: true });
objectStore.createIndex("domain", "domain", { unique: true, multiEntry: true });
Чтобы получить доступ к моим записям, я создал индекс, который ссылается на мое хранилище объектов. Ключевым путем индекса является domain
собственность моих записей.
Вот пример того, как может выглядеть одна запись в моем хранилище объектов:
{ domain: ["stackexchange",
"stackru",
"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("stackru");
};
Теперь вот часть, где я в замешательстве. Как только пользователь изменил свойства, которые он хочет редактировать, или добавил новые свойства по своему усмотрению, мне нужно сохранить их изменения, заменив полученный выше объект новым созданным пользователем объектом. (или измените исходный объект и сохраните изменения).
Я думаю, что мне нужно использовать IDBObjectStore.put()
сделать это.
put()
Метод принимает два параметра, один обязательный и один необязательный:
value
The value to be stored.
key
The key to use to identify the record. If unspecified, it results to null.
Второй параметр предположительно необязателен для случаев, когда вы используете встроенные ключи. Я использую ключи вне линии, которые были сгенерированы генератором ключей.
Как я могу получить (автоматически сгенерированный, вне строки) ключ объекта, который я извлек через свой индекс, чтобы я мог сообщить хранилищу объектов, что я хочу изменить этот ранее существующий объект, а не создавать новый один?
Есть ли другой способ, которым я должен идти об этом?
2 ответа
Ниже приведен текст из спецификации IndexedDB для индексов.
Каждый индекс также имеет уникальный флаг. Когда для этого флага установлено значение true, индекс обеспечивает, чтобы ни у двух записей в индексе не было одинакового ключа. Если попытаться вставить или изменить запись в хранилище объектов индекса, на которое ссылаются, таким образом, что при оценке пути ключа индекса для нового значения записей будет получен результат, который уже существует в индексе, тогда попытка модификации хранилища объектов завершится неудачно.
Таким образом, "put ()" нельзя использовать, если для этого свойства создан уникальный индекс. Таким образом, вместо этого вы можете создать первичный ключ, т.е. использовать keyPath при создании хранилища объектов.
var objectStore = db.createObjectStore("domains", {keyPath: "domain"});
Проверьте ниже 2 URL-адреса, которые помогут вам лучше понять, что невозможно выполнить обновление, если для него существует уникальный индекс.
Для будущих читателей. В качестве альтернативы использованию ключевого пути:
Вместо того, чтобы использовать IDBObjectStore.put()
Вы можете перебирать объекты в хранилище объектов с помощью IDBObjectStore.openCursor()
Как только вы нажмете на объект, который вы ищете, вы можете использовать:
IDBCursor.update()
если вы удалитеunique
свойство из индекса.IDBCursor.delete()
а потомIDBObjectStore.add()
если вам нужно сохранитьunique
какtrue
,