Как получить хранилище объектов из indexedDB?

У меня есть indexedDb в моем приложении для веб-хранилища.

Я хотел бы получить магазин из приведенного ниже кода.

var store = myapp.indexedDB.db.transaction(['tree_nodes'],'readwrite').objectStore('tree_nodes'); 

Он возвращает ошибку. Я был хорошо известен открытием базы данных indexeddb и изменением версии.

Ошибка Uncaught TypeError: Cannot call method 'transaction' of null

Я пробовал это с точкой останова. В этом случае все работает без ошибок.

Как я могу получить магазин? пожалуйста, помогите мне.

Заранее спасибо!


person kirankumar    schedule 10.08.2012    source источник


Ответы (2)


Ошибка, вероятно, связана с тем, что ваша переменная db имеет значение null. Это почти всегда происходит потому, что вы пытаетесь сохранить db в глобальной переменной в результате обратного вызова, а затем получить доступ к переменной db в отдельной функции, которая не гарантируется только после того, как ваша переменная db установлена, так что браузер обнаруживает, что вы обращаетесь к неинициализированной переменной.

Решение простое (но неприятное). Вы не можете использовать глобальную переменную таким образом, если только вы не хотите узнать о какой-либо библиотечной реализации промисов и отложенных объектов. Вместо этого посмотрите на ответ Дени. Используйте обратные вызовы и пишите свой код в функциях обратного вызова, а не в глобальных переменных. Доступ к 'db' осуществляется только из функции обратного вызова request.onsuccess, и он не является глобальным. Вот почему Дени сработает. Его код будет пытаться получить доступ к db только тогда, когда он гарантированно инициализирован (не нуль).

Поскольку вы не опубликовали окружающий код, что оказалось важным, вам нужно будет сделать что-то вроде этого:

// I am an evil global variable that will not work as expected
myapp.indexedDB.db = 'DO NOT USE ME OR YOU WILL GET AN ERROR';

// I am a good function that only accesses an initialized db variable
function doit() {
    var request = window.indexedDB.open(......);
    request.onsuccess = function(event) {
        // Use this db variable, not your global one
        var db = event.target.result;

            // Note that you can also access the db variable using other means
        // here like this.result or request.result, but I like to use event.target
        // for clarity.

        // Now work with the db variable
        var store = db.transaction(['tree_nodes'],'readwrite').objectStore('tree_nodes');
        // do some more stuff with store....
    };
}
person Josh    schedule 04.05.2013
comment
глобальная переменная была для меня. Я даже не использовал его, так что довольно легко удалить. - person Morten; 19.01.2015
comment
Джош, злобная глобальная переменная - это действительно хороший момент. Я видел, как многие люди получают ошибки, используя этот подход или IDB +1. - person Deni Spasovski; 29.01.2015

Вот вкратце, что вам нужно сделать, чтобы получить данные из indexeddb. Сначала вам нужно открыть базу данных, чтобы получить данные.

var request = indexedDB.open("tree_nodes", v); // first step is opening the database
request.onsuccess = function(e) {
        var db =  e.target.result;
        var trans = db.transaction(["tree_nodes"], 'readwrite'); //second step is opening the object store
        var store = trans.objectStore("tree_nodes");
        
        var request = store.get(id); //getting single object by id from object store
        
        request.onsuccess = function(e) {
            showDetails(e.target.result); // data retreived
            db.close();
        };
        
        request.onerror = function(e) {
                console.log("Error Getting: ", e);
        };
};
person Deni Spasovski    schedule 10.08.2012