使用indexedDB时,Object没有方法“打开”错误

时间:2012-03-30 06:04:44

标签: javascript html5 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对象下载数据并将它们存储到对象容纳的数组条目中。当我想将Entires的值存回DB时,我会调用dictionary.UploadDB();

但是,我收到了单个javascript错误:未捕获TypeError:对象#没有方法'打开'。对于我做错了什么,我几乎感到茫然。谁能给我一些提示?

1 个答案:

答案 0 :(得分:2)

执行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 here