-1

Chrome 30 で indexeddb からレコードを取得するための次のコードがあります。

var IndexedDBStorage = function (name) {
// until we won't need this prefix mess
var indexedDB = window.indexedDB || window.webkitIndexedDB
    || window.mozIndexedDB || window.msIndexedDB;
var IDBTransaction = window.IDBTransaction ||
    window.webkitIDBTransaction;
var db;
// The initialization of our stuff
this.Supported = function () {
    return indexedDB;
};
this.type = function () {
    return "IndexedDB";
};
this.Setup = function () {
    var dbVersion = 1.0;
    var openRequest = indexedDB.open(name, dbVersion);

    //handle setup - as the spec like it
    openRequest.onupgradeneeded = function (e) {
        console.log("running onupgradeneeded");
        var thisDb = e.target.result;
        if (!thisDb.objectStoreNames.contains(name)) {

            var objectStore = thisDb.createObjectStore(name, {
                autoIncrement: false
            });
            objectStore.createIndex("dataKey", "dataKey",
                { unique: false });
        }
    };

    openRequest.onsuccess = function (e) {
        db = e.target.result;
        db.onerror = function (event) {
            alert("Database error: " + event.target.errorCode);
            console.dir(event.target);
        };
        if (db.setVersion) {
            console.log("in old setVersion: " + db.setVersion);
            if (db.version != dbVersion) {
                var req = db.setVersion(dbVersion);
                req.onsuccess = function () {
                    var ob = db.createObjectStore(name, {
                        autoIncrement: false
                    });
                    ob.createIndex("datakey",
                        "datakey", { unique: false });
                    var trans = req.result;
                    trans.oncomplete = function (ex) {
                        console.log("== trans oncomplete ==");

                    };
                };
            }
        }
        console.log(db);

    };
};
this.GetAll = function (callback) {
    console.log(db);
    var transaction = db.transaction([name]); <-- gives error described below
    var store = transaction.objectStore(name);
    var items = [];

    transaction.oncomplete = function (evt) {
        callback(items);
    };

    var cursorRequest = store.openCursor();
    cursorRequest.onerror = function (error) {
        console.log(error);
    };

    cursorRequest.onsuccess = function (evt) {
        var cursor = evt.target.result;
        if (cursor) {
            items.push({ key: cursor.key, body: cursor.value.body });
            cursor.continue();
        }
    };
};


};

このようなボタンから呼び出すと、このようにしてボタンクリックから呼び出すと正常に動作します:

 function Init() { <-- called from script tag in index.html
$(document).ready(function () {

    window.dataStore = new Store("data");

});
}

function getAll() { <-- button lick function
window.dataStore.getAll();
}

ただし、このように初期化後に直接呼び出すと

function Init() {
$(document).ready(function () {

    window.dataStore = new Store("data");
window.dataStore.GetAll();

});
}

Uncaught TypeError: Cannot call method 'transaction' of undefinedというエラーが表示されます

initの直後に呼び出すと、db変数がまだopenRequest.onsuccessからグローバルに設定されていないためだと思います。

これを修正して正しく設定するにはどうすればよいですか

4

1 に答える 1

1

これは、indexedDB API の非同期動作によるものです。

onsucces がまだ呼び出されていないため、db 変数はまだ割り当てられていません。これを解決するには、openrequest で onsuccess が呼び出されたときにコールバックを提供するか、db 変数が未定義の場合は getAll 呼び出しの実行を遅らせる必要があります。

于 2013-10-16T09:23:26.530 に答える