如何附加到ID过滤后的IndexedDB中的数组?

时间:2018-10-05 10:28:10

标签: javascript indexeddb

初始化代码:

let dbPormise = null;
const OBJECT_STORE_NAME = 'pages';
const DB_NAME = 'tracking-log';

要启动ObjectStore:

  dbPromise = idb.open(DB_NAME, 3, upgradeDB => {
    upgradeDB.createObjectStore(OBJECT_STORE_NAME, {
      autoIncrement: true,
      keypath: 'id'
    });
  });

这是我在IndexedDB中生成空白记录的方式:

const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');

tx.objectStore(OBJECT_STORE_NAME).put(
    { id: newBucketID, data: [] });

现在,稍后,我要为特定的data附加一些元素到id数组中。

这是我尝试这样做的方式:

const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');

tx.objectStore(OBJECT_STORE_NAME).put(

{ id: localStorage.getItem("currentBucket"), data: item }

);

架构

{
  data: Array
}

每个项目都有我生成并提供的唯一密钥。

但是,这不起作用,并返回错误:“对象存储库中已存在密钥。”

那么,如何将值附加到IDB对象内的字段?

2 个答案:

答案 0 :(得分:0)

不确定该错误,但无论如何,添加项目的基本方法如下:

function addItem(db, bucketId, item) {
  return new Promise(addItemExecutor.bind(null, db, bucketId, item));
}

function addItemExecutor(db, bucketId, item, resolve, reject) {
  // Start a single writable transaction that we will use for two requests. One to 
  // find the corresponding bucket, and one to update it.
  const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');

  // If all requests completed without error, we are done
  tx.oncomplete = resolve;

  // If any request fails, the operation fails
  tx.onerror = event => reject(event.target.error);

  const store = tx.objectStore(OBJECT_STORE_NAME);

  // Go find the corresponding bucket object to update
  const findRequest = store.get(bucketId);
  findRequest.onsuccess = findRequestOnsuccess.bind(findRequest, bucketId, item, reject);
}

// React to the resolution of the get request
function findRequestOnsuccess(bucketId, item, reject, event) {
  const bucket = event.target.result;

  // If no bucket exists for that id then fail
  if(!bucket) {
    const error = new Error('No bucket found for id ' + bucketId);
    reject(error);
    return;
  }

  // Lazily init the data array property
  if(!bucket.data) {
    bucket.data = [];
  }

  // Add our item to the data array
  bucket.data.push(item);

  // Save the bucket object back into the bucket object store, completely replacing 
  // the bucket that was there before.
  const bucketStore = event.target.source;
  bucketStore.put(bucket);
}


async function someCallingCodeExampleAvoidingTopLevelAwait() {
  const bucketId = localStorage.currentBucket;
  const item = {foo:bar};

  const db = evilUnreliableGlobalDbVariableFromSomewhereMagicalForeverOpenAssumeInitialized;

  try {
    await addItem(db, bucketId, item);
  } catch(error) {
    console.debug(error);
  }

  // Leave the database connection open for page lifetime
}

答案 1 :(得分:0)

在没有简化示例的情况下,很难弄清发生了什么。寻求帮助的最佳方法是创建问题的简化示例,例如,使用最少的代码来重新创建您所遇到的问题,然后将其放在诸如jsbin.com或glitch.com之类的东西上,以便仅用于必须单击链接以查看所看到的错误。

我无法重新创建您看到的错误。您应该有keypath的{​​{1}},但是我认为这不会造成您看到的错误。

无论如何,这是在IDB中修改记录的方法:

keyPath

这是运行此示例:https://jsbin.com/dineguq/edit?js,console