У объекта нет метода «открыть», ошибка при использовании indexedDB - PullRequest
2 голосов
/ 30 марта 2012

Я пытаюсь создать небольшой классоподобный контейнер, который сделает его немного чище для загрузки и хранения данных из 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: У объекта # нет метода 'open' . Я в значительной степени в замешательстве относительно того, что я делаю неправильно. Может кто-нибудь предложить мне несколько советов?

1 Ответ

2 голосов
/ 30 марта 2012

Выполните проверку typeof и 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 здесь .

...