Arbeta med IndexedDB - Del 2

Välkommen till den andra delen av min IndexedDB-artikel. jag starkt rekommendera att läsa den första artikeln i den här serien, eftersom jag antar att du är bekant med alla begrepp som hittills tagits upp. I den här artikeln kommer vi att paketera upp de CRUD-aspekter som vi inte avslutade förut (specifikt uppdatering och radering av innehåll) och sedan visa en verklig applikation som vi ska använda för att visa andra begrepp i den slutliga artikeln.


Uppdatering av poster

Låt oss börja med att diskutera hur man uppdaterar en post med IndexedDB. Om du kommer ihåg det var ganska enkelt att lägga till data:

// Definiera en person var person = namn: namn, email: email, skapat: nytt datum () // Utför add var request = store.add (person);

Uppdatering av en post är lika enkel. Förutsatt att du har definierat en egendom som heter id Som din nyckel för objektobjektet kan du helt enkelt använda sätta metod istället för Lägg till.

var person = namn: namn, email: email, skapat: nytt datum (), id: someId // Utför uppdateringen var request = store.put (person);

Som Lägg till metod kan du tilldela metoder för att hantera de asynkrona resultaten av operationen.


Radera poster

Radera poster görs via raderingsmetoden. (Stor överraskning där.) Du skickar helt enkelt in den unika identifieraren av den post som du vill ta bort. Här är ett enkelt exempel:

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

Och som alla andra aspekter av IndexedDB kan du lägga till dina handtag för de asynkrona resultaten.

Så, som sagt, inte väldigt spännande, vilket är troligt bra. Du vill ha dina API: er enkla, tråkiga och otroliga. Låt oss nu ta vad vi har lärt oss och ta det tillsammans för att skapa en riktig, om enkel applikation.


Obs. App

Okej, äntligen har vi alla (de flesta) av de delar vi behöver för att bygga en riktig applikation. Eftersom det inte har gjorts tidigare (hm), kommer vi att bygga en enkel notering som tar ansökan. Låt oss titta på några skärmdumpar och sedan visar jag koden bakom den. Vid lanseringen initierar applikationen en IndexedDB för applikationen och gör en tom tabell. Ursprungligen kan allt du gör med programmet lägga till en ny anteckning. (Vi kan göra det lite mer användarvänligt kanske.)


Klicka på Lägg till anteckning knappen öppnar ett formulär:


Efter att ha fyllt i några uppgifter i formuläret kan du spara anteckningen:


Som du kan se har du möjlighet att redigera och radera anteckningar. Slutligen, om du klickar på raden själv kan du läsa anteckningen:


Så inte exakt raketvetenskap, men ett fullt fungerande exempel på IndexedDB-specifikationen. Anteckningarna skrivna här kommer att bestå. Du kan stänga din webbläsare, starta om datorn, ta några år av att tänka på liv och poesi, och när du öppnar webbläsaren igen kommer dina data fortfarande att finnas där. Låt oss ta en titt på koden nu.

Först - en ansvarsfriskrivning. Denna ansökan skulle ha varit en perfekt kandidat för en av de många JavaScript-ramarna. Jag är säker på att de som använder Backbone eller Angular kan föreställa sig hur du skulle ställa upp det här. Men - jag fattade det djärva beslutet här till inte använd en ram. Jag var orolig både för de människor som kan använda en annan ram och de som inte använder någon. Jag ville ha vårt fokus här för att vara enbart på IndexedDB-aspekterna. Jag förväntar mig fullt ut att vissa människor inte håller med det beslutet, men låt oss ha det i kommentarerna.

Vår första mall är HTML-filen. Vi har bara en och det mesta är boilerplate Bootstrap:

     Obs Databas     
Obs Databas

Redigera anteckning

Som nämnts ovan är en bra storlek av denna fil mallkod för Bootstrap. De delar vi bryr oss om är noteList div, the noteDetail div, och noteForm. Du kan nog gissa att det här är de DIV-filer vi uppdaterar när användaren klickar runt i programmet.

Kodning Vår Core App File

Låt oss nu ta en titt på app.js, kärnfilen som hanterar logiken för vår ansökan.

/ * global konsol, $, dokument, fönster, varning * / var db; funktion dtFormat (ingång) om (! input) returnera ""; var res = (input.getMonth () + 1) + "/" + input.getDate () + "/" + input.getFullYear () + ""; var timme = input.getHours (); var ampm = "AM"; om (timme === 12) ampm = "PM"; om (timme> 12) timme = 12; ampm = "PM";  var minut = input.getMinutes () + 1; if (minut < 10) minute = "0" + minute; res += hour + ":" + minute + " " + ampm; return res; 

Du kan ignorera den första funktionen eftersom det bara är ett formatverktyg för datum. Låt oss gå vidare till det jQuery-dokumentklara blocket.

Söker efter webbläsarstöd

 $ (dokument) .ready (funktion () if (! ("(indexedDB" i fönstret)) alert ("IndexedDB-stöd krävs för denna demo!"); return; var $ noteDetail = $ ("# noteDetail") ; var $ noteForm = $ ("# noteForm"); var openRequest = window.indexedDB.open ("netuts_notes_1", 1); openRequest.onerror = function (e) console.log ("Error opening db"); .dir (e);; openRequest.onupgradeneeded = function (e) var thisDb = e.target.result; var objectStore; // Skapa Obs OS om (! thisDb.objectStoreNames.contains ("note")) konsol .log ("Jag måste göra noteringsobjektet"); objectStore = thisDb.createObjectStore ("notera", keyPath: "id", autoIncrement: true);; openRequest.onsuccess = funktion (e) db = e.target.result; db.onerror = funktion (händelse) // Generisk felhanterare för alla fel riktade mot denna databas // requests! alert ("Databasfel:" + event.target.errorCode); console.dir (event.target);; displayNotes ();;

Vår allra första åtgärd är att kontrollera IndexedDB-support. Om användarens webbläsare inte är kompatibel använder vi en varning och avbryter funktionen. Det skulle förmodligen vara bättre att flytta dem till en sida som förklarar varför de inte kan använda applikationen. (Och för att vara tydligt kan vi också bygga en applikation som utnyttjade WebSQL som backup. Men igen - mitt fokus är här på enkelhet.)

Efter att ha cached några jQuery selectors, som vi använder hela appen öppnar vi vår IndexedDB-databas. Databasen är ganska enkel. I onupgradeneeded handler kan du se en objektaffär som heter anteckningar skapas. När allt är klart, är det onsuccess handler kommer att avfyra ett samtal till displayNotes.

De displayNotes Fungera

 funktion displayNotes () var transaction = db.transaction (["note"], "readonly"); var innehåll = ""; transaktion.oncomplete = funktion (händelse) $ (" # notislista "). html (innehåll);; varhandResultat = funktion (händelse) varare = event.target.result; if (cursor) content + = ""; innehåll + =""; innehåll + =""; innehåll + =""; cursor.continue (); else content + ="
TitelUppdaterad 
"+ Cursor.value.title +""+ DtFormat (cursor.value.updated) +"Redigera radera
";; var objectStore = transaction.objectStore (" notera "); objectStore.openCursor (). onsuccess = handleResult;

De displayNotes funktionen gör vad du förväntar dig - få all data och visa den. Vi diskuterade hur man får alla rader av data i föregående post, men jag vill påpeka något lite annorlunda om detta exempel. Observera att vi har en ny händelsehanterare, oncomplete, att vi har bundet till själva transaktionen. Tidigare har vi använt händelser precis inom åtgärderna, inuti Transaktionen, men IndexedDB låter oss göra det på toppnivå också. Detta blir särskilt användbart i ett sådant fall. Vi har en jätte sträng, vårt HTML-bord, som vi bygger upp över varje iteration av våra data. Vi kan använda transaktionen oncomplete handler för att pakka upp bildskärmsdelen och skriva ut den med ett enkelt jQuery-samtal.

De Radera, Redigera, och Lägg till funktioner

 $ ("# noteList"). På ("klicka", "a.delete", funktion (e) var thisId = $ (this) .parent (). parent () .data ("key"); var = db.transaction ("not"), "readwrite"); var request = t.objectStore ("notera"). radera (thisId); t.oncomplete = funktion (händelse) displayNotes (); $ noteDetail.hide (); $ noteForm.hide ();; return false;); $ ("# noteList"). På ("klicka", "a.edit", funktion (e) var thisId = $ (detta) .parent (). parent (). data ("key"); varförfrågan = db.transaction ("not"), "readwrite") .objectStore ("notera") .get (thisId); request.onsuccess = funktion (händelse) var notera = request.result; $ ("# key" ) .val (note.id); $ ("# title") .val (note.title); $ ("# body") .val (note.body); $ noteDetail.hide (); $ noteForm.show ();; return false;); $ ("# noteList") på ("klicka", "td", funktion () var thisId = $ (detta) .parent () .data ("nyckel"); var transaction = db.transaction note "]; var objectStore = transaction.objectStore (" notera "); var request = objectStore.get (thisId); request.onsuccess = funktion (händelse) var note = request.result; $ noteDetail.html ("

"+ Note.title +"

"+ Note.body +"

"(), $ noteForm.hide ();;); $ (" # addNoteButton "). $ ("# body") .val (""); $ ("# key") .val (""); $ noteDetail.hide (); $ noteForm.show (););

Våra två närmaste metoder (radera och redigera) är ett annat exempel på samma rektor. Eftersom ingen av IndexedDB-samtalen här är nya kommer vi inte att bry sig om dem. Det mesta av köttet här slutar bli en enkel DOM-manipulation för att hantera de särskilda åtgärderna. Hanteraren för att klicka på add-knappen är exakt det, så vi hoppar över det också.

De Spara Fungera

 $ ("# saveNoteButton") på ("klicka", funktion () var title = $ ("# title") .val (); var body = $ ("# body"). = $ ("# key") .val (); var t = db.transaction (["notera"], "readwrite"), om (nyckel === "") t.objectStore ("notera"). lägg till (title: title, body: body, updated: new Date (); else t.objectStore ("note") .put (title: title, body: body, updated: new Date id (nummer)); t.oncomplete = funktion (händelse) $ ("# key") .val (""); $ ("# title" #body ") .val (" "); displayNotes (); $ noteForm.hide ();; return false;); );

Nästa intressanta tidbit är spara metod. Det måste använda lite logik för att avgöra om vi lägger till eller uppdaterar, men även det är ganska enkelt. Och det är allt! En komplett, om enkel IndexedDB-applikation. Du kan spela med den här demonen själv genom att ladda ner den bifogade källkoden.


Sammanfattningsvis

Det är det för del två! Den tredje artikeln tar den här applikationen och börjar lägga till ytterligare funktioner, inklusive sök- och arraybaserade egenskaper.