首页 > 解决方案 > 在 IndexedDB 的数组中推送值

问题描述

我想在 IndexedDB 的数组中推送值。但似乎 put() 方法替换/覆盖了现有数据。

const idbPromise = async() => {
  try {
    const db = await openDB("first", 1, {
      // dbx, oldVersion, newVersion, transaction
      upgrade(dbx) {
        if (!dbx.objectStoreNames.contains(storeName)) {
          dbx.createObjectStore("data", {
            keyPath: "name"
          });
        }
      }
    });

    return db;
  } catch (error) {
    return error;
  }
};


const appendData = async(value) => {
  return idbPromise()
    .then(function(db) {
      const tx = db.transaction("data", "readwrite");
      const store = tx.objectStore("data");
      store.put(data);
      return tx.complete;
    })
    .catch(e => console.log(e));
}

// first call
appendData({
  name: "arr",
  value: [1]
});

// second call
appendData({
  name: "arr",
  value: [2]
});

上面代码的输出是value: [2]但我想实现value: [1,2].
我将如何实现这一目标?

PS:我不想复制现有值并将其全部添加,我希望它像 JavaScript 的push()方法一样工作。

标签: javascriptindexeddb

解决方案


正如 Josh 建议的唯一方法是读取对象然后更新它 - 这是一个用纯 js 编写的示例,因为我没有您正在使用的 openDb 脚本。

const appendData = (newValue) => {
    return new Promise(function(resolve, reject){
        const request = indexedDB.open("todos");
        request.onsuccess = (e) => {
            const db = e.target.result;
            const trans = db.transaction(["data"],"readwrite");
            const store = trans.objectStore("data");

            const openCursorReq = store.openCursor(IDBKeyRange.only(newValue.name));
            openCursorReq.onsuccess = (event) => {
                const cursor = event.target.result;
                let oldValue = cursor.value;
                oldValue.value = oldValue.value.concat(newValue.value);
                var updateRequest = cursor.update(oldValue);
                updateRequest.onerror = updateRequest.onblocked = () => {
                    
                    console.log('Error updating');
                    reject();
                };

                updateRequest.onsuccess = function (event) {
                    console.log('update', newValue);
                    resolve();
                };

                trans.oncomplete = function(e) {
                    db.close();
                };
            }
        };
        request.onerror = reject;
    })
};


推荐阅读