У объекта нет метода "открыть", ошибка при использовании indexedDB

Я пытаюсь создать небольшой классоподобный контейнер, который сделает загрузку и хранение данных из HTML5 IndexedDB немного чище. Честно говоря, я впервые играю с этой функцией, поэтому моя проблема может быть тривиальной.

Я основываю свой код на этом уроке: http://www.html5rocks.com/en/tutorials/indexeddb/todo/

function DBDictionary()
{
    this.Holder = {};
    this.Entries = new Array();
    this.Opened = false;
    this.v = "1.0";
    this.Holder.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;

    if ('webkitIndexedDB' in window)
    {
        window.IDBTransaction = window.webkitIDBTransaction;
        window.IDBKeyRange = window.webkitIDBKeyRange;
    }

    this.Holder.indexedDB = {};
    this.Holder.indexedDB.db = null;

    this.Holder.indexedDB.onerror = function(e) 
    {
        console.log(e);
    };

    this.DownloadDB = function()
    {
        if(this.Opened) return;
        var request = this.Holder.indexedDB.open("Storage");
        request.onsuccess = function(e)
        {
            this.Holder.indexedDB.db = e.target.result;
            var db = this.Holder.indexedDB.db;
            // We can only create Object stores in a setVersion transaction;
            if (v!= db.version)
            {
                var setVrequest = db.setVersion(v);

                // onsuccess is the only place we can create Object Stores
                setVrequest.onerror = this.Holder.indexedDB.onerror;
                setVrequest.onsuccess = function(e)
                {
                    if(db.objectStoreNames.contains("Storage")) db.deleteObjectStore("Storage");
                    var store = db.createObjectStore("Storage", {keyPath: "Key"});
                    this.PopulateAll();
                };
            }
            else
            {
                this.PopulateAll();
            }
        };

        request.onerror = this.Holder.indexedDB.onerror;
    };

    this.UploadDB = function()
    {       
        this.DeleteAll();
        this.SaveAll();
    };

    this.DeleteAll = function()
    {
        var db = this.Holder.indexedDB.db;
        var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE);
        var store = trans.objectStore("Storage");

        Entries.forEach(function(element, index, array)
        {
            var request = store.delete(index);

            request.onerror = function(e)
            {
                console.log("Error Deleting: ", e);
            };
        });
    };

    this.PopulateAll = function()
    {
        var db = this.Holder.indexedDB.db;
        var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE);
        var store = trans.objectStore("Storage");

        // Get everything in the store;
        var keyRange = IDBKeyRange.lowerBound(0);
        var cursorRequest = store.openCursor(keyRange);

        cursorRequest.onsuccess = function(e)
        {
            var result = e.target.result;

            //No more results to load
            if(!!result == false)
            {
                if(!this.Opened) this.Opened = true;
                return;
            }

            this.Entries[result.Key] = result.Value;
            result.continue();
        };

        cursorRequest.onerror = this.Holder.indexedDB.onerror;
    };

    this.SaveAll = function()
    {
        var db = this.Holder.indexedDB.db;
        var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE);
        var store = trans.objectStore("Storage");

        Entries.forEach(function(element, index, array)
        {
            var data = {
                "Key": index,
                "Value": element,
                "timeStamp": new Date().getTime()
            };

            var request = store.put(data);

            request.onerror = function(e) {
                console.log("Error Adding: ", e);
            };
        });
    };
}

function main()
{
    var dictionary = new DBDictionary();
    dictionary.DownloadDB();

    dictionary.Entries["hello"] = "world";
    alert(dictionary.Entries["hello"]);
}

$(document).ready(main);

Мое желаемое реализованное состояние должно выглядеть примерно так:

function main()
{
    var dictionary = new DBDictionary();
    dictionary.DownloadDB();

    dictionary.Entries["hello"] = "world";
    alert(dictionary.Entries["hello"]);
}

$(document).ready(main);

Для этого необходимо загрузить данные из объекта IndexedDB браузера и сохранить их в объектном массиве Entries. Когда я хочу сохранить значение Entires обратно в БД, я бы вызвал dictionary.UploadDB();

Тем не менее, я получаю единственную ошибку JavaScript: Uncaught TypeError: Object # не имеет метода "open". Я в значительной степени в замешательстве относительно того, что я делаю неправильно. Может кто-нибудь предложить мне несколько советов?

1 ответ

Решение

Сделайте проверку типа и console.log this.Holder.indexedDB Объект для проверки прототипа. Это наследует IDBDatabase прототип? Если это так, то open метод будет доступен для вас.

Если твой window.indexedDB выстрелил при успешном обратном вызове, e.target.result будет правильным способом доступа к вновь открытой базе данных через объект события. Но тот факт, что вы не зашли так далеко, говорит о том, что ваш this.Holder.indexedDB объект на самом деле не является экземпляром IDBDatabase,

РЕДАКТИРОВАТЬ: Да, это именно ваша проблема. Если вы console.log объекта this.holder.indexedDB, вы получите объект, который выглядит как {"db":null},

Своп this.Holder.indexedDB за window.webkitIndexedDB в твоем open вызов, и вы увидите, что всплывает предупреждение "мир". JSFiddle здесь.

Другие вопросы по тегам