Einfache Verwendung der indexedDB

Ich orientiere mich hier einfach mal an meinem JavaScript-Framework cJS, dass Methoden zur Verfügung stellt, um JavaScript Objekte in der indexedDB unter einem Namen zu speichern und wieder zu laden. Auch hier ist der komplizierteste Teil eigentlich, dass man alles wieder asynchron durchführen muss.
Also wenn man etwas laden möchte muss man auch eine Callback-Function mitgeben. Aber gerade wenn man mit AngularJS und $http arbeitet, ist dass ja schon sehr vertraut und man muss sich die indexedDB wie ein REST-Service vorstellen, dann kommt man gut damit zurecht.


this.putToDataStore=function(name,obj,longtime){
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(window.indexedDB){
var request = window.indexedDB.open("cjs_", 1);

request.onupgradeneeded=function(event){
var db = event.target.result;
console.log("need to create cjs datastore");
db.createObjectStore("datastore", { keyPath : "cjsDataStoreIndex" });
};

request.onsuccess=function(event){
var db=event.target.result;
var transaction = db.transaction(["datastore"],"readwrite");
var objectStore = transaction.objectStore("datastore");
obj.cjsDataStoreIndex=name;
objectStore.put(obj);
};
}
else{
console.log("ERROR: indexeddb not supported!");
}
};


Sollte die indexedDB nicht verfügbar zu sein, kann man immer noch ein Fallback auf ein einfaches Array einbauen, damit wenigstens zur Laufzeit die Daten zur Verfügung stehen. Im Gegensatz zur indexedDB gehen diese Daten dann natürlich verloren, wenn man das Tab/Fenster im Browser schließt.

Erstmal wird die Datenbank geöffnet:

var request = window.indexedDB.open("cjs_", 1);


Das erste ist der Name der Datenbank und das zweite die Version der Datenbank. Sollte die Datebank nicht vorhanden sein, wird die Version auch nicht stimmen. Wenn die Version nicht stimmt wird onupgradeneeded ausgelöst.

Sollte ein Upgrade nötig sein wird dieser Code ausgeführt:

var db = event.target.result;
console.log("need to create cjs datastore");
db.createObjectStore("datastore", { keyPath : "cjsDataStoreIndex" });


Damit wird in der Datenbank ein neuer Objectstore erzeugt. Unseren haben wir hier auch ganz einfach "datastore" genannt. Der keyPath ist die Id des Objekts anhand der wir das Objekt später auch wieder finden werden. Die Id kann ein beliebiger String sein. Also ist es hier der Name unter dem wir ein Object speichern und wollen und mit dem wir es auch wieder laden.

Das Speichern ist auch relativ einfach (der Code wird ausgeführt, wenn das open() erfolgreich war):

var db=event.target.result;
var transaction = db.transaction(["datastore"],"readwrite");
var objectStore = transaction.objectStore("datastore");
obj.cjsDataStoreIndex=name;
objectStore.put(obj);


Wir öffnen wieder unseren "datastore". Dann fügen wir einfach ein Attribute für unsere Id hinzu. Sollte es nicht existieren wird es damit auch gleich angelegt. Und dann speichern wir das Object. Auf eine Callback-Function haben wir hier verzichtet, aber man könnte darüber zurück liefern, ob das Speichern erfolgreich war oder nicht. Aber wir gehen hier einfach mal
davon aus, dass es das auch immer war.


Nun kommen wir zum Laden:

this.getFromDataStore=function(name,callBack){
var func=function(fn,requ){
return function(event){
fn(requ.result);
};
};

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(window.indexedDB && callBack){
var request = window.indexedDB.open("cjs_", 1);

request.onupgradeneeded=function(event){
var db = event.target.result;
db.createObjectStore("datastore", { keyPath : "cjsDataStoreIndex" });
};

request.onsuccess=function(event){
var db=event.target.result;
var transaction = db.transaction(["datastore"],"readwrite");
var objectStore = transaction.objectStore("datastore");
var req=objectStore.get(name);
req.onsuccess=func(callBack,req);
};
}
else{
console.log("ERROR: indexeddb not supported!");
if(callBack!=null){
callBack(null);
}
}
};


Im Grunde ist der Code dem oberen sehr ähnlich. Nur das hier kein put sondern ein get mit unserer Id (also dem Namen unter dem wir das Objekt gespeichert haben) aufgerufen wird.
Wir erhalten wieder ein Request-Object, dem wir wieder eine onsuccedd-function zu weisen. Wir haben uns eine function gebaut die über ein Closure-Konstrukt ein function zurück liefert, die das Event erhält und das Result (ein JavaScript-Object) aus dem Request (das wir auch an unsere function übergeben hatten) an unsere Callback-function übergibt.

Es gibt natürlich noch viel mehr Dinge die man mit der indexedDB tun kann als einfaches Speichern und Laden über eine Id, aber für die meisten Anwendungsfälle sollte dies schon reichen.


Mir hat bei dem Thema das MDN sehr geholfen.

bbcode-image


Um die Ansicht zu haben muss man in den Einstellungen diesen Punkt aktivieren.
bbcode-image
User annonyme 2015-07-30 21:25

write comment:
Six + = 9

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?