1

我正在尝试使用 index.openCursor(keyRange.only 或 keyRange.bound 此处提供) 使用使用autoIncrement: true创建的表上的索引访问一个或多个记录。我尝试了多种变体,但没有成功。有人可以使用以下代码作为模板向我展示一个工作示例:

window.indexedDB = window.indexedDB || window.webkitIndexedDB 
                || window.mozIndexedDB || window.msIndexedDB;
var ixDb; 

var ixDbIndexTest = function () {
  //Open or create the requested IndexedDB Database
  var ixDbRequest = window.indexedDB.open("testDBindexes", 2);

  ixDbRequest.onupgradeneeded = function (e) {
    ixDb = ixDbRequest.result || e.currentTarget.result;

    objectStore = 
      ixDb.createObjectStore("demoOS", 
                             { keyPath: "id", autoIncrement: true });
    objectStore.createIndex("ixdemo", "Field1",
                             { unique: false, multiEntry: false });

    //define new dummy record  
    var newRecord = {};
    newRecord.Field1 = "222";
    newRecord.Field2 = "333";
    newRecord.Field3 = "444";

    var request = objectStore.add(newRecord);

    request.onsuccess = function (e) {
      var index = objectStore.index('ixdemo');
      var range = IDBKeyRange.only("222");
      var cursorRequest = index.openCursor(range);

      cursorRequest.onsuccess = function(e) {    
        var cursor = cursorRequest.result || e.result; 
        alert(cursor.value);
        cursor.continue();
      }
    }
  };
};

window.onload = ixDbIndexTest;

更新: 我修改了演示脚本以在 Firefox 和仍然使用 setVersion 的旧 Chrome 版本中工作。但是,您需要为 Chrome 添加额外的版本检查逻辑,因为每次脚本运行时当前逻辑都会运行 setVersion。

window.indexedDB = window.indexedDB || window.webkitIndexedDB 
                || window.mozIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction 
                    || window.mozIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || 
                     window.mozIDBKeyRange || window.msIDBKeyRange;

var ixDb;     
var ixDbIndexTest = function () {
  //Open or create the requested IndexedDB Database
  var ixDbRequest = window.indexedDB.open("testDBindexes", 1);

  ixDbRequest.onsuccess = function(e) {
    ixDb = ixDbRequest.result || e.currentTarget.result;

    if (typeof ixDb.setVersion === "function") {
      ixDbVersionRequest = ixDb.setVersion(1);

      ixDbVersionRequest.onsuccess = function (e) {
        indexTest();
      };
     }
     else {
       ixDbRequest.onupgradeneeded = function (e) {
       indexTest(); 
       };
     }
   }
 };

window.onload = ixDbIndexTest;

function indexTest() {
  var objectStore = ixDb.createObjectStore("demoOS", 
                           { keyPath: "id", autoIncrement: true });
  objectStore.createIndex("ixdemo", "Field1", 
                           { unique: false, multiEntry: false });

  //define new record with users input 
  var newRecord = {};
  newRecord.Field1 = "222";
  newRecord.Field2 = "333";
  newRecord.Field3 = "444";

  var request = objectStore.add(newRecord);

  request.onsuccess = function (e) {
    var index = objectStore.index('ixdemo');
    var range = IDBKeyRange.only("222");
    var cursorRequest = index.openCursor();

    cursorRequest.onsuccess = function(e) {    
      var cursor = cursorRequest.result || e.result; 
      if(cursor) {
        alert(JSON.stringify(cursor.value));
        cursor.continue();
      }
    }
  }
}
4

2 回答 2

4

出现错误消息Type Error: cursor is undefined是因为您使用游标而不检查它是否已定义。因此,当cursor.continue()告诉 IndexedDB 去获取数据库中的下一个对象时,游标在耗尽唯一实际存在的对象后将是未定义的。

所以你应该做这样的事情。在您的代码中,它看起来像:

      cursorRequest.onsuccess = function(e) {    
        var cursor = cursorRequest.result || e.result;
        if (cursor) {
          alert(cursor.value);
          cursor.continue();
        }
      }

此外,如果您知道您只在寻找一个对象(例如当您使用 时IDBKeyRange.only),您可以省略该cursor.continue()部分:

      cursorRequest.onsuccess = function(e) {    
        var cursor = cursorRequest.result || e.result;
        alert(cursor.value);
      }

至于您的 Chrome 问题,我无法帮助您,因为到目前为止我只关注 Firefox。我建议您尝试最新的 Chrome 开发版本,它实际上支持onupgradeneeded各种其他更新,但在我的测试中,到目前为止它仍然存在相当多的错误,并且在 Firefox 中运行的代码在 Chrome 中可能会失败。如果这不是一个紧急项目,您最好等待一段时间让 Chrome 稳定下来。

于 2012-09-03T19:33:17.397 回答
0

在 onupgardeneded 事件中不能添加记录。

更改版本后,您必须重新打开数据库以获取新的 objectStore 架构。所以会有两个开

当前的 chrome 是,我认为仍然是旧标准,setVersion,onupgardeneeed 永远不会调用。

newRecord 必须具有 keyPath 'id',否则您不应在创建对象存储时指定 keyPath。

于 2012-09-03T15:05:21.680 回答