indexedDB objectStore.get() 总是 returns undefined 尽管在 DB 中有结果

indexedDB objectStore.get() always returns undefined despite results in DB

我一直在改造一个旧项目并进行一些改进,但我似乎无法再弄清楚如何从 indexedDB 加载单个条目。我已经清除了数据库并进行了全新导入,我可以在 chrome 检查员资源部分中看到所有记录(包括我用于 entryID 的记录)。我试过提取各种 ID 号,我可以确认所有这些都在检查员的数据库中,它们都 return 未定义。这是我正在使用的代码。

/*
    This loads up a specific entry and fills in the #entry-details div with it's data. This div is placed overtop the search 
    content so that when it is closed the user remains exactly where they were and the search does not need to re-process.
*/
function getEntryDetails(){

    var entryID = 193; // just for now, this will be grabbed from somewhere else later

    // Where going to need a varible to store all this generated HTML in
    var html = '';

    // First we need to load up the indexedDB and get the record in question.
    var db = indexedDB.open('pediaCache');

    // lets get a couple of the errors out of the way.
    db.onerror=function(e){html += 'There was an error loading the database.<br/>'+e;}
    db.onblocked=function(e){html += 'Database access blocked.<br/>'+e;}

    // Now for when things go the right way
    db.onsuccess=function(e){
        var db = e.target.result;

        // Get the requested entry
        console.log('Attempting to load entry ID '+entryID);
        var transaction = db.transaction(['entries'],'readonly');
        var objectStore = transaction.objectStore('entries');
        var entry = objectStore.get(entryID);

        entry.onerror = function(e) {
            console.log('error');
            console.log(e.target.result);
            console.log(e);
        };
        entry.onsuccess = function(e) {
            console.log('success');
            console.log(e.target.result);
            console.log(e);
        };

    }

}

这实际上只是对原始版本稍作修改的代码(由于此功能相同,我实际上只修改了此处和导入程序中的数据库和 ObjectStore 名称)。在 Chrome 中运行此代码(在我知道所有其他与数据库相关的功能完成后手动触发)确实会触发 "onsuccess" 甚至,只是结果未定义(就好像该条目不在数据库中一样,但是我再次检查它在那里)。

根据要求,console.dir(e)的内容:

{
    "path": {
        "length": 0
    },
    "cancelBubble": false,
    "returnValue": true,
    "srcElement": {
        "readyState": "done",
        "transaction": {
            "onerror": null,
            "oncomplete": null,
            "onabort": null,
            "error": null,
            "db": {
                "onversionchange": null,
                "onerror": null,
                "onclose": null,
                "onabort": null,
                "objectStoreNames": {
                    "0": "entries",
                    "length": 1
                },
                "version": 3,
                "name": "pediaCache"
            },
            "mode": "readonly"
        },
        "source": {
            "autoIncrement": false,
            "transaction": {
                "onerror": null,
                "oncomplete": null,
                "onabort": null,
                "error": null,
                "db": {
                    "onversionchange": null,
                    "onerror": null,
                    "onclose": null,
                    "onabort": null,
                    "objectStoreNames": {
                        "0": "entries",
                        "length": 1
                    },
                    "version": 3,
                    "name": "pediaCache"
                },
                "mode": "readonly"
            },
            "indexNames": {
                "0": "title",
                "length": 1
            },
            "keyPath": null,
            "name": "entries"
        },
        "error": null
    },
    "defaultPrevented": false,
    "timeStamp": 1420434102528,
    "cancelable": false,
    "bubbles": false,
    "eventPhase": 0,
    "currentTarget": null,
    "target": {
        "readyState": "done",
        "transaction": {
            "onerror": null,
            "oncomplete": null,
            "onabort": null,
            "error": null,
            "db": {
                "onversionchange": null,
                "onerror": null,
                "onclose": null,
                "onabort": null,
                "objectStoreNames": {
                    "0": "entries",
                    "length": 1
                },
                "version": 3,
                "name": "pediaCache"
            },
            "mode": "readonly"
        },
        "source": {
            "autoIncrement": false,
            "transaction": {
                "onerror": null,
                "oncomplete": null,
                "onabort": null,
                "error": null,
                "db": {
                    "onversionchange": null,
                    "onerror": null,
                    "onclose": null,
                    "onabort": null,
                    "objectStoreNames": {
                        "0": "entries",
                        "length": 1
                    },
                    "version": 3,
                    "name": "pediaCache"
                },
                "mode": "readonly"
            },
            "indexNames": {
                "0": "title",
                "length": 1
            },
            "keyPath": null,
            "name": "entries"
        },
        "error": null
    },
    "type": "success"
}

以及 objectStore 创建(需要升级)。

    // We need to be able to update the db schema (or create it for that matter)
    db.onupgradeneeded=function(e){
        var db = e.target.result;

        // In the future some of theme might want to get commented out...
        postMessage({'status':'importing','message':'Upgrading local database.'});
        // Check if the table is in there, if it's not then create it
        console.log(db.objectStoreNames);
        if(db.objectStoreNames.contains('entries')==false){
            var db = db.createObjectStore('entries');

            // Create the indexes so we can more easily search and sort and stuff (just one, we sort by name, everything else done by magic)
            db.createIndex('title'  ,'ZTITLE'   ,{unique:false});

        }

    };

找到问题了,希望没有人犯我犯过的同样简单的错误,但万一有人犯了这个问题并遇到了这个问题,这就是问题所在。

我添加到数据库中的键是一个字符串。我要求的密钥是一个整数。

不要像我一样,检查你的数据类型。

创建 index/store 时使用适当的 keyPath。 以下表达方式不一样!

store.createIndex(this.indexes.prevNodeKey, "prevNodeKey");
store.createIndex(this.indexes.prevNodeKey, ["prevNodeKey"]);
db.createObjectStore(this.storeNames.configs, {keyPath: "price"});
db.createObjectStore(this.storeNames.configs, {keyPath: ["price"]});

我用数组 keyPath 创建了一个索引,然后即使类型相同也无法从索引中查询任何内容。

可能,如果您将 keyPath 定义为数组,那么您应该使用数组进行查询:

someIndex.getKey(["value"]))