Arbeiten mit IndexedDB - Teil 2

Willkommen zum zweiten Teil meines IndexedDB-Artikels. ich stark Ich empfehle Ihnen, den ersten Artikel dieser Serie zu lesen, da ich davon ausgehe, dass Sie mit allen bisher behandelten Konzepten vertraut sind. In diesem Artikel werden wir die CRUD-Aspekte, die wir vorher noch nicht abgeschlossen haben (insbesondere das Aktualisieren und Löschen von Inhalten) zusammenfassen, und dann eine reale Anwendung demonstrieren, die wir verwenden werden, um andere Konzepte im abschließenden Artikel zu demonstrieren.


Datensätze aktualisieren

Beginnen wir mit der Erörterung, wie ein Datensatz mit IndexedDB aktualisiert wird. Wenn Sie sich erinnern, war das Hinzufügen von Daten ziemlich einfach:

// Eine Person definieren var person = Name: Name, E-Mail: E-Mail, erstellt: neues Datum () // Füge das Hinzufügen hinzu var request = store.add (person);

Das Aktualisieren eines Datensatzes ist genauso einfach. Angenommen, Sie haben eine aufgerufene Eigenschaft definiert Ich würde Als Schlüssel für Ihren Objektspeicher können Sie einfach den stellen Methode statt hinzufügen.

var person = name: name, email: email, erstellt: neues Datum (), id: someId // Update durchführen var request = store.put (person);

Wie hinzufügen Methode können Sie Methoden zuweisen, um die asynchronen Ergebnisse der Operation zu behandeln.


Datensätze löschen

Das Löschen von Datensätzen erfolgt über die Löschmethode. (Große Überraschung dort.) Sie geben einfach die eindeutige Kennung des Datensatzes weiter, den Sie entfernen möchten. Hier ist ein einfaches Beispiel:

 var t = db.transaction (["people"], "readwrite"); var request = t.objectStore ("Personen"). delete (thisId);

Und wie jeder andere Aspekt von IndexedDB können Sie Ihre Handles für die asynchronen Ergebnisse hinzufügen.

Also, wie gesagt, nicht besonders aufregend, was wahrscheinlich gut ist. Sie möchten, dass Ihre APIs einfach, langweilig und nicht überraschend sind. Nehmen wir jetzt das Gelernte und bringen es zusammen, um eine echte, wenn auch einfache Anwendung zu erstellen.


Die Notiz-App

Ok, endlich haben wir alle Teile (naja, die meisten), um eine echte Anwendung zu erstellen. Da es noch nie gemacht wurde (Hm), werden wir eine einfache Notiz erstellen, die die Anwendung übernimmt. Schauen wir uns ein paar Screenshots an und dann zeige ich Ihnen den Code dahinter. Beim Start initialisiert die Anwendung eine IndexedDB für die Anwendung und rendert eine leere Tabelle. Zunächst können Sie mit der Anwendung nur eine neue Notiz hinzufügen. (Wir könnten das vielleicht ein bisschen benutzerfreundlicher machen.)


Klicken Sie auf die Notiz hinzufügen Schaltfläche öffnet ein Formular:


Nachdem Sie einige Daten in das Formular eingegeben haben, können Sie die Notiz speichern:


Wie Sie sehen, haben Sie die Möglichkeit, Notizen zu bearbeiten und zu löschen. Wenn Sie schließlich auf die Zeile klicken, können Sie den Hinweis lesen:


Also nicht gerade eine Raketenwissenschaft, sondern ein voll funktionsfähiges Beispiel für die IndexedDB-Spezifikation. Die hier geschriebenen Notizen bleiben bestehen. Sie können Ihren Browser schließen, Ihren Computer neu starten und sich ein paar Jahre Zeit nehmen, um über Leben und Gedichte nachzudenken. Wenn Sie den Browser erneut öffnen, sind Ihre Daten immer noch vorhanden. Schauen wir uns jetzt den Code an.

Erstens - ein Haftungsausschluss. Diese Anwendung wäre ein perfekter Kandidat für eines der vielen JavaScript-Frameworks gewesen. Ich bin sicher, dass diejenigen, die Backbone oder Angular verwenden, sich bereits vorstellen können, wie Sie dies einrichten würden. Allerdings habe ich hier die mutige Entscheidung getroffen nicht Verwenden Sie einen Rahmen. Ich machte mir sowohl um die Menschen Sorgen, die möglicherweise einen anderen Rahmen verwenden, als auch um die, die keinen Rahmen verwenden. Ich wollte, dass wir uns hier ausschließlich auf die IndexedDB-Aspekte konzentrieren. Ich erwarte durchaus, dass einige Leute mit dieser Entscheidung nicht einverstanden sind, aber lassen Sie uns in den Kommentaren darauf eingehen.

Unsere erste Vorlage ist die HTML-Datei. Wir haben nur einen und das meiste davon ist Boilerplate Bootstrap:

     Beachten Sie die Datenbank     
Beachten Sie die Datenbank

Notiz bearbeiten

Wie oben erwähnt, besteht ein guter Teil dieser Datei aus Vorlagencode für Bootstrap. Die Teile, die uns wichtig sind, sind die noteList div, der noteDetail div und die noteForm. Sie können wahrscheinlich davon ausgehen, dass dies die DIVs sind, die wir aktualisieren, wenn der Benutzer in der Anwendung klickt.

Kodierung unserer Core-App-Datei

Lass uns einen Blick darauf werfen app.js, Die Kerndatei, die die Logik für unsere Anwendung verarbeitet.

/ * globale Konsole, $, Dokument, Fenster, Warnung * / var db; Funktion dtFormat (Eingabe) if (! Eingabe) return ""; var res = (input.getMonth () + 1) + "/" + input.getDate () + "/" + input.getFullYear () + ""; var hour = input.getHours (); var ampm = "AM"; if (hour === 12) ampm = "PM"; wenn (Stunde> 12) Stunde- = 12; ampm = "PM";  var minute = input.getMinutes () + 1; wenn (Minute < 10) minute = "0" + minute; res += hour + ":" + minute + " " + ampm; return res; 

Sie können die erste Funktion ignorieren, da es sich lediglich um ein Formatierungsprogramm für Datumsangaben handelt. Lassen Sie uns zum jQuery-Dokument-Ready-Block springen.

Auf Browser-Unterstützung prüfen

 $ (document) .ready (function () if (! ("indexedDB" in window)) alert ("IndexedDB-Unterstützung für diese Demo erforderlich!"); return; var $ noteDetail = $ ("# noteDetail") var $ noteForm = $ ("# noteForm"); var openRequest = window.indexedDB.open ("nettuts_notes_1", 1); openRequest.onerror = function (e) console.log ("Fehler beim Öffnen von db"); console .dir (e);; openRequest.onupgradeneeded = Funktion (e) var thisDb = e.target.result; var objectStore; // Create Note OS if (! thisDb.objectStoreNames.contains ("note")) Konsole .log ("Ich muss den Hinweis objectstore erstellen"); objectStore = thisDb.createObjectStore ("note", keyPath: "id", autoIncrement: true);; openRequest.onsuccess = function (e) db = e.target.result; db.onerror = function (event) // Generischer Fehlerhandler für alle Fehler, die auf die // Anforderungen dieser Datenbank gerichtet sind! alert ("Datenbankfehler:" + event.target.errorCode); console.dir (event.target);; displayNotes ();;

Unsere allererste Aktion besteht darin, nach IndexedDB-Unterstützung zu suchen. Wenn der Browser des Benutzers nicht kompatibel ist, verwenden wir eine Warnung und brechen die Funktion ab. Es ist wahrscheinlich besser, sie auf eine Seite zu verschieben, auf der vollständig erklärt wird, warum sie die Anwendung nicht verwenden können. (Um es klar zu sagen, wir könnten auch eine Anwendung erstellen, die WebSQL als Backup verwendet. Aber auch hier - mein Hauptaugenmerk liegt auf der Einfachheit.)

Nach dem Zwischenspeichern einiger jQuery-Selektoren, die wir in der gesamten App verwenden, öffnen wir unsere IndexedDB-Datenbank. Die Datenbank ist ziemlich einfach. In dem onupgradededed Handler können Sie einen Objektspeicher sehen Anmerkungen erschaffen werden. Sobald alles fertig ist, das Ein Erfolg Handler feuert einen Anruf an displayNotes.

Das displayNotes Funktion

 function displayNotes () var transaction = db.transaction (["note"], "readonly"); var content = ""; transaction.oncomplete = function (event) $ (" # noteList "). html (content);; var handleResult = function (event) var Cursor = event.target.result; if (Cursor) content + = ""; Inhalt + =""; Inhalt + =""; Inhalt + =""; Cursor.continue (); else content + ="
TitelAktualisierte 
"+ cursor.value.title +""+ dtFormat (cursor.value.updated) +"Bearbeiten Löschen
";; var objectStore = transaction.objectStore (" note "); objectStore.openCursor (). onsuccess = handleResult;

Das displayNotes Funktion macht, was Sie erwarten - alle Daten abrufen und anzeigen. Wir haben besprochen, wie alle Datenzeilen im vorherigen Eintrag abgerufen werden können, aber ich möchte etwas auf dieses Beispiel hinweisen. Beachten Sie, dass wir einen neuen Ereignishandler haben, unvollständig, dass wir uns an die Transaktion selbst gebunden haben. Bisher haben wir Ereignisse nur innerhalb der Aktionen verwendet, Innerhalb die Transaktion, aber mit IndexedDB können wir dies auch auf oberster Ebene tun. Dies ist besonders nützlich in einem solchen Fall. Wir haben eine riesige Zeichenfolge, unsere HTML-Tabelle, die wir bei jeder Wiederholung unserer Daten aufbauen. Wir können die Transaktion nutzen unvollständig Handler, um den Anzeigeabschnitt zusammenzufassen und mit einem einfachen jQuery-Aufruf auszugeben.

Das Löschen, Bearbeiten, und Hinzufügen Funktionen

 $ ("# noteList"). on ("click", "a.delete"), Funktion (e) var thisId = $ (this) .parent (). parent (). data ("key"); var t = db.transaction (["note"], "readwrite"); var request = t.objectStore ("note"). delete (thisId); t.oncomplete = function (event) displayNotes (); $ noteDetail.hide (); $ noteForm.hide ();; false zurückgeben;); $ ("# noteList"). on ("click", "a.edit"), Funktion (e) var thisId = $ (this) .parent (). parent (). data ("key"); var request = db.transaction (["note"], "readwrite") .objectStore ("note") .get (thisId); request.onsuccess = function (event) var note = request.result; $ ("# key") ) .val (note.id); $ ("# title"). val (note.title); $ ("# body"). val (note.body); $ noteDetail.hide (); $ noteForm.show (); ; falsch zurückgeben; ); $ ("# noteList"). on ("click", "td", function () var thisId = $ (this) .parent (). data ("Schlüssel"); var transaction = db.transaction ([" note "]); var objectStore = transaction.objectStore (" note "); var request = objectStore.get (thisId); request.onsuccess = function (Ereignis) var note = request.result; $ noteDetail.html ("

"+ note.title +"

"+ note.body +"

") .show (); $ noteForm.hide ();;); $ (" # addNoteButton "). on (" click "), Funktion (e) $ (" # title "). val (" " ); $ ("# body"). val (""); $ ("# key"). val (""); $ noteDetail.hide (); $ noteForm.show (););

Unsere nächsten zwei Methoden (löschen und bearbeiten) ist ein weiteres Beispiel dieses Prinzips. Da keiner der IndexedDB-Aufrufe hier neu ist, werden wir uns nicht darum kümmern. Der Großteil des "Fleisches" ist hier eine einfache DOM-Manipulation, um die jeweiligen Aktionen auszuführen. Der Handler für das Klicken auf die Schaltfläche "Hinzufügen" ist genau das, also überspringen wir das ebenfalls.

Das sparen Funktion

 $ ("# saveNoteButton"). on ("click") function () var title = $ ("# title"). val (); var body = $ ("# body"). val (); var-Taste = $ ("# key"). val (); var t = db.transaction (["note"], "readwrite"); if (key === "") t.objectStore ("note"). add (title: title, body: body, aktualisiert: neues Datum ()); else t.objectStore ("note") .put (title: title, body: body, aktualisiert: neues Datum (), id: Number (key)); t.oncomplete = function (event) $ ("# key"). val (""); $ ("# title"). val (""); $ (" #body "). val (" "); displayNotes (); $ noteForm.hide ();; return false;); );

Der nächste interessante Leckerbissen ist der sparen Methode. Es muss ein bisschen Logik verwendet werden, um zu bestimmen, ob wir etwas hinzufügen oder aktualisieren, aber selbst das ist ziemlich einfach. Und das ist es! Eine vollständige, wenn auch einfache IndexedDB-Anwendung. Sie können mit dieser Demo selbst herumspielen, indem Sie den beigefügten Quellcode herunterladen.


Abschließend

Das wars für den zweiten Teil! Der dritte Artikel nimmt diese Anwendung in Anspruch und fängt an, zusätzliche Funktionen hinzuzufügen, darunter Such- und Array-basierte Eigenschaften.