如何从IndexedDb对象库

时间:2017-01-30 16:23:28

标签: angularjs indexeddb

有人可以建议如何从IndexedDB objectstore获取多个键值吗?我做了多个选项,但没有做任何事。 在这里创建了indexedDb

$provide.value('dbModel', {
        name: 'TestDB',
        version: '1',
        instance: {},
        objectStoreName: {
            dashboards: 'Appointment'
        },
        upgrade: function (e) {
            var db = e.target.result;
            if (!db.objectStoreNames.contains('Appointment')) {
                var calendarobj = db.createObjectStore('Appointment', {
                    keyPath: 'AppointmentId'
                });
                calendarobj.createIndex("AppointmentId", "AppointmentId", { multiEntry: true });
            }
        }
    });

数据看起来像

KeyPath-AppointmentId             Value
=====================             =====
1                                 Test 1
2                                 Test 2
3                                 Test 3

我有getObjectStore方法来获取objectstorename实例。

getObjectStore: function (objectStoreName, mode) {
            var modeact = mode || _db.transactionTypes.readonly;
            var txn = _db.instance.transaction(objectStoreName, modeact);
            var store = txn.objectStore(objectStoreName);

            return store;
        }


var keys = [1,2]; // Want to get the First two record which has value 'Test 1' and 'Test 2'
var store = _db.getObjectStore(objectStoreName);
var tagIndex = store.index(store.keyPath); //AppointmentId

var request = tagIndex.openCursor(IDBKeyRange.only(keys));
//var request = tagIndex.get(keys);

request.onsuccess = function (event) {
                console.log(event.result);
}

2 个答案:

答案 0 :(得分:3)

使用[1, 2],因为您确实无法工作 - 这是一个恰好是有两个成员的数组的密钥。索引数据库目前不了解使用列表或密钥集进行查询。

您有一些选择:

1 - 并行发出两个get请求。 (由于订单有保证,第二个请求将在第一个请求之后完成,您知道两个结果都将被返回。)

var results = [];
store.get(1).onsuccess = function(e) {
  results.push(e.target.result);
};
store.get(2).onsuccess = function(e) {
  results.push(e.target.result);

  // results will have the values
};

2 - 使用光标和范围:

var results = [];
store.openCursor(IDBKeyRange.bound(1, 2)).onsuccess = function(e) {
  var cursor = e.target.result;
  if (cursor) {
    results.push(cursor.value);
    cursor.continue();
  } else {
    // results will have the values
  }
};

3 - 将getAll与范围一起使用(仅限较新的浏览器 - 如果不可用,则返回光标)

store.getAll(IDBKeyRange.bound(1, 2)).onsuccess = function(e) {
  // e.target.result will have the entries
};

请注意,在使用范围的选项2和3中,如果存在密钥,您还会获得密钥为1.5的记录。

答案 1 :(得分:2)

这可以与Multiple keys query in IndexedDB (Similar to OR in sql)复制,但是我无权报告重复,因此我将再次发布答案。希望对您有所帮助。

使用Promise

// [store]: object store
// [keys]: array of keys
// return: An object of key-value pairs
const get = (store, keys) =>
  Promise.all(
    keys.map(
      (key) =>
        new Promise((resolve, reject) => {
          const request = store.get(key);
          request.onsuccess = ({ target: { result } }) => resolve(result);
          request.onerror = ({ target: { error } }) => reject(error);
        })
    )
  ).then((values) =>
    keys.reduce(
      (result, key, index) => ((result[key] = values[index]), result),
      {}
    )
  );

示例

const request = indexedDB.open("test");
request.onupgradeneeded = ({ target: { result: db } }) => {
  db.createObjectStore("settings").transaction.oncomplete = ({
    target: { db },
  }) => {
    const store = db
      .transaction("settings", "readwrite")
      .objectStore("settings");
    store.add(123, "foo");
    store.add(456, "bar");
  };
};
request.onsuccess = ({ target: { result: db } }) => {
  get(db.transaction("settings").objectStore("settings"), [
    "foo",
    "bar",
    "buz",
  ]).then(console.log); // {foo: 123, bar: 456, buz: undefined}
};