Javascript 为什么我会看到;类型错误:光标未定义";当使用indexedDB时?

Javascript 为什么我会看到;类型错误:光标未定义";当使用indexedDB时?,javascript,html,indexeddb,Javascript,Html,Indexeddb,我正在尝试使用index.openCursor(此处提供的keyRange.only或keyRange.bound)访问一个或多个记录,该记录是使用autoIncrement:true创建的表上的索引访问的。我尝试了多种变体,但都没有成功。是否有人可以使用以下代码作为模板向我展示一个工作示例: window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB

我正在尝试使用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();
      }
    }
  }
}

在OnupGardeRequired事件中不能添加记录

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

我认为当前的chrome仍然是旧的标准,setVersion,onupgardeneeded是永不调用的


newRecord必须具有密钥路径“id”,否则不应在创建对象存储时指定密钥路径

在事件中,您不能添加记录

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

我认为当前的chrome仍然是旧的标准,setVersion,onupgardeneeded是永不调用的


newRecord必须具有密钥路径“id”,否则不应在创建对象存储时指定密钥路径

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

所以你应该做一些类似的事情。在您的代码中,它看起来像:

      cursorRequest.onsuccess = function(e) {    
        var cursor = cursorRequest.result || e.result;
        if (cursor) {
          alert(cursor.value);
          cursor.continue();
        }
      }
此外,如果您知道只查找一个对象(例如使用
IDBKeyRange.only
),则可以省略
光标。continue()
部分:

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

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

错误消息
类型错误:光标未定义
,因为您在使用光标时没有检查光标是否已定义。因此,当
cursor.continue()
告诉IndexedDB去获取数据库中的下一个对象时,游标将在耗尽实际存在的唯一对象后被取消定义

所以你应该做一些类似的事情。在您的代码中,它看起来像:

      cursorRequest.onsuccess = function(e) {    
        var cursor = cursorRequest.result || e.result;
        if (cursor) {
          alert(cursor.value);
          cursor.continue();
        }
      }
此外,如果您知道只查找一个对象(例如使用
IDBKeyRange.only
),则可以省略
光标。continue()
部分:

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

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

也许我没有抓住重点,但你的代码似乎可以工作。它显示数据库中的条目。你到底有什么问题?有错误消息吗?@Jeremy关于添加记录的说法是正确的。但是,索引似乎没有正常工作,或者我没有正确使用它???当我在Firefox的web控制台中查看时,会收到错误消息“Type error:cursor is undefined”。我似乎无法通过index.openCursor()调用使用range.bound()或range.only()返回游标。此外,当我通过setVersion命令在Chrome中运行此代码时,您可以看到添加的记录,但索引似乎从未使用每个插入填充。我已经尝试添加keyPath:id,但仍然无法使其工作。当我将keyPath:id添加到createObjectStore命令时,add()调用期望在我发送的对象中提供{id:value},并且自动增量不再是“自动增量”…如果我按如下方式更改警报:警报(JSON.stringify(cursor.value));我确实在Firefox中得到了一个记录值,但我仍然得到了TypeError:“游标未定义”…也许我没有抓住要点,但您的代码似乎可以工作。它显示数据库中的条目。你到底有什么问题?有错误消息吗?@Jeremy关于添加记录的说法是正确的。但是,索引似乎没有正常工作,或者我没有正确使用它???当我在Firefox的web控制台中查看时,会收到错误消息“Type error:cursor is undefined”。我似乎无法通过index.openCursor()调用使用range.bound()或range.only()返回游标。此外,当我通过setVersion命令在Chrome中运行此代码时,您可以看到添加的记录,但索引似乎从未使用每个插入填充。我已经尝试添加keyPath:id,但仍然无法使其工作。当我将keyPath:id添加到createObjectStore命令时,add()调用期望在我发送的对象中提供{id:value},并且自动增量不再是“自动增量”…如果我按如下方式更改警报:警报(JSON.stringify(cursor.value));我确实在Firefox中得到了一个记录值,但仍然得到了类型错误:“游标未定义”…您可以在
onupgradeneeded
中添加记录。例如,见。Chrome 23支持
onupgradeneeded
。如果它是自动递增的,你不需要指定
id
,事实就是如此