У объекта нет метода "открыть", ошибка при использовании 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 здесь.