"无法调用方法'交易'未定义" indexedDB中的错误

时间:2014-03-26 17:54:49

标签: javascript indexeddb

以下是我的代码。它第一次运行正常但是一旦我刷新页面就会生成一个未被捕获的TypeError:无法调用未定义的方法'transaction'。

基本上我从数据库中检索数据并将其编码为可用的JSON数据类型,以避免在我的表中插入问题。

$(document).ready( function() {

//prefixes of implementation that we want to test
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;

//prefixes of window.IDB objects
window.IDBTransaction = window.IDBTransaction ||
                        window.webkitIDBTransaction ||
                        window.msIDBTransaction;

window.IDBKeyRange = window.IDBKeyRange ||
                     window.webkitIDBKeyRange ||
                     window.msIDBKeyRange

if(!window.indexedDB){ //alert user if browser does not support
    window.alert("Your browser doesn't support a stable version of IndexedDB.")
}

var request = window.indexedDB.open("runningClub", 1); //create a runningClub database

var browserDB;

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

var raceIDs = [];

$(".raceID").each( function () {
    raceIDs.push(" raceID = " + $(this).val());
});

$.ajax({
    url: 'controller/AJAX/userAction.php',
    type: 'post',
    dataType: 'json',
    data: { statement : "getRaceResult", raceIDs : raceIDs },
    success: function(data) {

        const results = data;

        request.onupgradeneeded = function(event){
            var browserDB = event.target.result;
            var objectStore = browserDB.createObjectStore("raceResult", {keyPath: "resultID"});
            for(var i in results){
                objectStore.add(results[i]);       
            }
        }

        var objectStore = browserDB.transaction("raceResult").objectStore("raceResult");

        objectStore.openCursor().onsuccess = function(event){
            var cursor = event.target.result;
            if (cursor){
                $("#memberName").append("<option>" + cursor.value.memberName + "</option>");
                cursor.continue();
            }
        };
    }
});
});

1 个答案:

答案 0 :(得分:2)

感谢您发布(几乎)全部代码。遗憾的是,在不知道来自后端的数据对象结构的情况下,我无法完全复制您的问题。心灵出版也是如此?

那就是说,我确定你的问题是使用const

const results = data;

我不相信这种类型的数据是&#34; structured clone&#34; -able。鉴于JSON是完全可克隆的,这是我想象从您的API返回的(例如,可以被评估为生成function的JavaScript),使用此关键字似乎可能是您的问题的罪魁祸首。

更新1 解决这个问题,您的异步编程存在很多问题。

  • 数据库在ajax请求之前打开,而不是在成功回调之后打开。将这一点转化为回调似乎是谨慎的。
  • browserDBsuccess回调中定义,并且在异步操作完成之前保证不会运行(因此browserDB变为未定义)
  • request.onsuccess被调用两次(你可能没有意识到这一点,因为它有奇怪的行为):当没有upgradeneeded事件触发且upgradeneeded事件触发时,因此,当数据库尚不存在时,您可能会意外地重新定义browserDB

更新2 这是一个主要工作的人,simplified Fiddle。我为花费你的代码工作花了多少时间而感到很难过。

更多问题(超出const):

  • 硬编码数据库版本
  • 重新使用versionchange事件来添加/获取数据是一个坏主意
  • 需要使用readwrite交易来添加数据
  • openCursor - 但不提供resultID keypath的参数
  • 在获取数据之前,您没有收听成功添加
  • 在获取数据之前,您没有为成功事件链接

当前的循环方法是站不住脚的。但我得到它与单个添加和光标get工作。您可以重构为多重添加方法,但是您需要观察异步(基于我看到的内容,我建议您坚持使用简单)。

$.ajax({
  url: '/echo/json/',
  type: 'post',
  dataType: 'json',
  data: {
    json: JSON.stringify({
      resultID: new Date().getTime(),
      raceID: "1",
      memberID: "824",
      runtime: "00:31:26",
      memberName‌: "Mark Hudspith"
    })
  },
  success: function (data) {
    var request,
      upgrade = false,
      doTx = function (db, entry) {
        addData(db, entry, function () {
          getData(db);
        });
      },
      getData = function (db) {
        db.transaction(["raceResult"], "readonly").objectStore("raceResult").openCursor(IDBKeyRange.lowerBound("0")).onsuccess = function (event) {
          var cursor = event.target.result;
          if (null !== cursor) {
            console.log("YOUR DATA IS HERE", cursor.value.memberName‌);
            cursor.continue();
          }
        };
      },
      addData = function (db, entry, finished) {
        var tx = db.transaction(["raceResult"], "readwrite");
        tx.addEventListener('complete', function (e) {
          finished();
        });
        tx.objectStore("raceResult").add(entry);
      };
    request = window.indexedDB.open("runningClub");
    request.onsuccess = function (event) {
      if (!upgrade) {
        doTx(request.result, data);
      }
    };
    request.onupgradeneeded = function (event) {
      var db = event.target.result;
      db.createObjectStore("raceResult", {
        keyPath: "resultID"
      });
      setTimeout(function () {
        doTx(db, data);
      }, 5000);
    }
  }
});