Lucrul cu IndexedDB

Una dintre cele mai interesante evoluții în standardele web în ultima vreme este specificația bazei de date indexate (IndexedDB pentru scurt). Pentru un timp de distracție puteți citi singur speculația. În acest tutorial voi explica această caracteristică și, sperăm, vă oferă o inspirație pentru a utiliza această caracteristică puternică.


Prezentare generală

Ca o specificație, IndexedDB este în prezent o recomandare pentru candidat.

Pe scurt, IndexedDB oferă o modalitate prin care puteți stoca cantități mari de date pe browserul utilizatorului. Orice aplicație care are nevoie pentru a trimite o mulțime de date pe fir ar putea beneficia în mare măsură de posibilitatea de a stoca acele date pe client în schimb. Desigur, depozitarea este doar o parte a ecuației. IndexedDB oferă, de asemenea, un puternic API de căutare bazat pe indexare pentru a prelua datele de care aveți nevoie.

S-ar putea să vă întrebați cum IndexedDB diferă de alte mecanisme de stocare?

Cookie-urile sunt extrem de bine susținute, dar au implicații legale și spațiu redus de stocare. De asemenea, ele sunt trimise înainte și înapoi la server cu fiecare solicitare, negând complet beneficiile stocării de pe partea clientului.

Depozitarea locală este, de asemenea, foarte bine susținută, dar limitată în ceea ce privește cantitatea totală de stocare pe care o puteți utiliza. Stocarea locală nu oferă un API adevărat "căutare", deoarece datele sunt preluate numai prin intermediul valorilor-cheie. Depozitarea locală este excelentă pentru lucrurile "specifice" pe care doriți să le stocați, de exemplu preferințele, în timp ce IndexedDB este mai potrivit pentru datele ad hoc (la fel ca o bază de date).

Înainte de a merge mai departe, totuși, să vorbim cinstit despre starea IndexedDB în ceea ce privește suportul pentru browser. Ca o specificație, IndexedDB este în prezent o recomandare pentru candidat. În acest moment, oamenii din spatele specificației sunt mulțumiți de aceasta, dar caută acum feedback de la comunitatea dezvoltatorilor. Specificația se poate schimba între momentul actual și cel final, Recomandarea W3C. În general, browserele care acceptă IndexedDB toate acum fac într-o manieră destul de consistentă, dar dezvoltatorii ar trebui să fie pregătiți să se ocupe de prefixe și să ia act de actualizări în viitor.

În ceea ce privește acele browsere care susțin IndexedDB, aveți o mică dilemă. Sprijinul este destul de darn bun pentru desktop, dar practic inexistent pentru mobil. Să vedem ce excelent site-ul CanIUse.com spune:


Chrome pentru Android nu acceptă această funcție, însă foarte puțini oameni utilizează în prezent browserul respectiv pe dispozitive Android. Lipsa suportului mobil presupune că nu ar trebui să o utilizați? Desigur că nu! Sperăm că toți cititorii noștri sunt familiarizați cu conceptul de îmbunătățire progresivă. Caracteristici ca IndexedDB pot fi adăugate la aplicația dvs. într-un mod care nu se va rupe în browserele care nu sunt acceptate. Puteți utiliza bibliotecile de tip wrapper pentru a comuta la WebSQL pe mobil sau pur și simplu săriți stocarea datelor la nivel local pe clienții dvs. de telefonie mobilă. Personal cred că abilitatea de a cache blocuri mari de date pe client este suficient de importantă pentru a putea folosi chiar acum, chiar și fără suport mobil.


Să începem

Am acoperit caietul de sarcini și suportul, acum să ne uităm la utilizarea acestei caracteristici. Primul lucru pe care ar trebui să-l facem este să verificăm suportul IndexedDB. În timp ce există instrumente care oferă metode generice pentru a verifica caracteristicile browserului, putem face acest lucru mult mai simplu, deoarece doar verificăm un anumit lucru.

document.addEventListener ("DOMContentLoaded", funcția () if ("indexedDB" în fereastră) console.log ("YES !!!") else console.log ("Am un trist");, fals);

Fragmentul de cod de mai sus (disponibil în test1.html dacă descărcați fișierul zip atașat la acest articol) utilizează DOMContentLoaded să așteptați încărcarea paginii. (Bine, acest lucru este destul de evident, dar recunosc că este posibil să nu fie familiari care au folosit doar jQuery.) Apoi văd pur și simplu dacă indexedDB există în fereastră obiect și, dacă da, suntem bine să mergem. Acesta este cel mai simplu exemplu, dar, de obicei, probabil că vom dori să stocăm acest lucru, așa că știm mai târziu dacă putem folosi această caracteristică. Iată un exemplu ușor mai avansat (test2.html).

var idbSupported = false; document.addEventListener ("DOMContentLoaded", funcția () if ("indexedDB" în fereastră) idbSupported = true;, false);

Tot ce am făcut este creată o variabilă globală, idbSupported, care poate fi folosit ca steag pentru a vedea dacă browserul curent poate utiliza IndexedDB.


Deschiderea unei baze de date

IndexedDB, după cum vă puteți imagina, face uz de baze de date. Pentru a fi clar, aceasta nu este o implementare SQL Server. Această bază de date este localizată în browser și este disponibilă numai pentru utilizator. Bazele de date IndexedDB respectă aceleași reguli ca și cookie-urile și spațiul de stocare local. O bază de date este unică pentru domeniul din care a fost încărcat. De exemplu, o bază de date numită "Foo" creată la foo.com nu va intra în conflict cu o bază de date cu același nume la goo.com. Nu numai că nu va intra în conflict, ci și în alte domenii. Puteți să stocați date pentru site-ul dvs. web, știind că un alt site web nu va putea accesa site-ul.

Deschiderea unei baze de date se face prin comanda deschisă. În utilizarea de bază furnizați un nume și o versiune. Versiunea este foarte important pentru motive, voi acoperi mai târziu. Iată un exemplu simplu:

var deschisRequest = indexedDB.open ("test", 1);

Deschiderea unei baze de date este o operație asincronă. Pentru a gestiona rezultatul acestei operațiuni, va trebui să adăugați anumiți ascultători de evenimente. Există patru tipuri diferite de evenimente care pot fi concediate:

  • succes
  • eroare
  • upgradeneeded
  • blocat

Probabil că puteți ghici ce succes și eroare implică. Evenimentul upgradeneeded este folosit atât atunci când utilizatorul deschide mai întâi baza de date, cât și atunci când schimbați versiunea. Blocat nu este ceva care se va întâmpla de obicei, dar se poate declanșa dacă o conexiune anterioară nu a fost niciodată închisă.

În mod obișnuit, ceea ce ar trebui să se întâmple este că, la primul hit pe site-ul dvs., evenimentul upgradeneeded va declanșa. După aceea - doar un manipulator de succes. Să examinăm un exemplu simplu (test3.html).

var idbSupported = false; var db; document.addEventListener ("DOMContentLoaded", funcția () if ("indexedDB" în fereastră) idbSupported = true; if (idbSupported) openRequest = indexedDB.open ("test", openRequest.onupgradeneeded = (e) console.log ("Actualizarea ..."); openRequest.once = funcția (e) console.log ("Succes! ) console.log ("Eroare"); console.dir (e);, false);

Încă o dată, verificăm dacă IndexedDB este de fapt suportat și, dacă este, deschidem o bază de date. Am acoperit trei evenimente aici - evenimentul de actualizare necesar, evenimentul de succes și evenimentul de eroare. Pentru moment, concentrați-vă asupra evenimentului de succes. Evenimentul este trecut printr-un handler target.result. Am copiat acest lucru la o variabilă globală numită db. Acesta este un lucru pe care îl vom folosi ulterior pentru a adăuga date. Dacă rulați acest lucru în browserul dvs. (într-unul care acceptă IndexedDB desigur!), Ar trebui să vedeți mesajul de actualizare și de succes din consola dumneavoastră la prima executare a scriptului. A doua, și așa mai departe, ori de câte ori executați scriptul, trebuie să vedeți mesajul de succes.


Magazine de obiecte

Până acum, am verificat suportul IndexedDB, l-am confirmat și am deschis o conexiune la o bază de date. Acum avem nevoie de un loc pentru stocarea datelor. IndexedDB are un concept de "Obiecte Stores". Vă puteți gândi la acest lucru ca la o tabelă tipică de baze de date. (Este mult mai liber decât o tabelă tipică de baze de date, dar nu vă faceți griji acum.) Magazinele de obiecte au date (în mod evident), dar și o cale de acces și un set opțional de indici. Datele cheie sunt identificatori unici pentru datele dvs. și vin în câteva formate diferite. Anumitele vor fi acoperite mai târziu când începem să vorbim despre recuperarea datelor.

Acum pentru ceva crucial. Amintiți-vă evenimentul upgradeneeded menționat anterior? Puteți crea numai obiecte în timpul unui eveniment upgradeneeded. Acum - în mod implicit - acest lucru se va executa automat la prima accesare a unui site de către un utilizator. Puteți folosi acest lucru pentru a crea magazinele de obiecte. Lucrul crucial pe care trebuie să-l amintiți este dacă vreți vreodată modifica obiectele stocate, va trebui să actualizați versiunea (înapoi în acel eveniment deschis) și să scrieți cod pentru a vă ocupa de modificările dvs. Să aruncăm o privire la un exemplu simplu al acestei acțiuni.

var idbSupported = false; var db; document.addEventListener ("DOMContentLoaded", funcția () if ("indexedDB" în fereastră) idbSupported = true; if (idbSupported) openRequest = indexedDB.open ("test_v2", openRequest.onupgradeneeded = (e) console.log ("running onupgradeneeded"); var thisDB = e.target.result; if (! thisDB.objectStoreNames.contains ("firstOS")) thisDB.createObjectStore ("firstOS"); openRequest Funcția (e) console.log ("Eroare"); db = e.target.result; openRequest.onerror = funcția (e) console.log );   ,fals);

Acest exemplu (test4.html) se bazează pe intrările anterioare, așa că mă voi concentra doar asupra a ceea ce este nou. În cadrul evenimentului upgradeneeded, am folosit varianta bazei de date care i-a fost transmisă (thisDB). Una dintre proprietățile acestei variabile este o listă de magazine de obiecte existente numite objectStoreNames. Pentru oameni curioși, aceasta nu este o matrice simplă, ci un "DOMStringList". Nu mă întreba - dar te duci acolo. Putem folosi conține pentru a vedea dacă magazinul nostru de obiecte există și, dacă nu, creați-l. Aceasta este una dintre puținele funcții sincrone din indexedDB, deci nu trebuie să ascultăm rezultatul.

Pentru a rezuma apoi - acesta este ceea ce s-ar întâmpla când un utilizator vizitează site-ul dvs. Prima dată când sunt aici, evenimentul upgradeneeded se declanșează. Codul verifică dacă un magazin de obiecte "firstOS" există. Nu va. Prin urmare - este creat. Apoi, managerul de succes rulează. A doua oară când vizitează site-ul, numărul versiunii va fi același, astfel încât evenimentul upgradeneeded este nu dat afara.

Acum, imaginați-vă că doriți să adăugați un al doilea magazin de obiecte. Tot ce trebuie să faceți este să creșteți numărul versiunii și să duplicați în esență blocul de coduri / createObjectStore pe care îl vedeți mai sus. Lucrul atractiv este că codul tău upgradeneed va susține atât cei care sunt nou în site, cât și cei care au avut deja primul magazin de obiecte. Iată un exemplu de acest lucru (test5.html):

var openRequest = indexedDB.open ("test_v2", 2); openRequest.onupgradeneeded = funcția (e) console.log ("running onupgradeneeded"); var thisDB = e.target.result; dacă (! thisDB.objectStoreNames.contains ("firstOS")) thisDB.createObjectStore ("firstOS");  dacă (! thisDB.objectStoreNames.contains ("secondOS")) thisDB.createObjectStore ("secondOS"); 

Adăugarea de date

Odată ce ați pregătit galeria de obiecte, puteți începe să adăugați date. Acesta este - poate - unul dintre cele mai tari aspecte ale IndexedDB. Spre deosebire de bazele de date tradiționale bazate pe tabele, IndexedDB vă permite să stocați un obiect ca atare. Ce înseamnă asta înseamnă că poți să iei un obiect generic JavaScript și să-l stochezi. Terminat. Evident, există câteva avertismente aici, dar, în cea mai mare parte, asta este.

Lucrul cu datele vă cere să utilizați o tranzacție. Tranzacțiile au două argumente. Primul este o serie de mese cu care veți lucra. De cele mai multe ori, acesta va fi un tabel. Al doilea argument este tipul de tranzacție. Există două tipuri de tranzacții: readonly și readwrite. Adăugarea datelor va fi o operație de read-write. Să începem prin crearea tranzacției:

// Assume db este o variabilă de bază de date deschisă mai devreme transaction = db.transaction (["people"], "readwrite");

Rețineți că magazinul de obiecte, "oameni", este doar unul pe care l-am făcut în exemplul de mai sus. Următoarea demonstrație completă va face uz de aceasta. După ce ați primit tranzacția, îl întrebați apoi despre magazinul de obiecte cu care ați spus că veți lucra:

var stoc = transaction.objectStore ("persoane");

Acum, că aveți magazinul puteți adăuga date. Acest lucru se face prin - așteptați-l - adăuga metodă.

// Definirea unei persoane var person = nume: nume, email: email, creat: new Date () // Efectuați add var request = store.add (person, 1);

Amintiți-vă mai devreme am spus că puteți stoca orice date doriți (în cea mai mare parte). Deci, persoana mea obiect de mai sus este complet arbitrară. Aș fi putut folosi numele și ultimul nume în loc de nume. Aș fi putut folosi o proprietate de gen. Ai idee. Al doilea argument este cheia utilizată pentru identificarea unică a datelor. În acest caz, am codificat greu la 1, ceea ce va cauza o problemă destul de repede. Asta e ok - vom învăța cum să o corectăm.

Funcția de adăugare este asincronă, deci permite adăugarea a două procesatoare de evenimente pentru rezultat.

request.onerror = funcția (e) console.log ("Eroare", e.target.error.name); // un tip de handler de eroare request.onsuccess = funcția (e) console.log ("Woot! Did it"); 

Avem un onerror handler pentru erori și onsuccess pentru schimbări bune. Destul de evident, dar să vedem un exemplu complet. Puteți găsi acest lucru în fișier test6.html.

>
      

Exemplul de mai sus conține o formă mică, cu un buton pentru a declanșa un eveniment pentru stocarea datelor în IndexedDB. Rulați acest lucru în browserul dvs., adăugați ceva în câmpurile de formular și faceți clic pe adăugați. Dacă aveți instrumentele browserului dvs. dev deschise, ar trebui să vedeți ceva de genul acesta.


Acesta este un moment excelent pentru a sublinia faptul că Chrome are un vizualizator excelent pentru datele IndexedDB. Dacă faceți clic pe fila Resurse, extindeți secțiunea IndexedDB, puteți vedea baza de date creată de această demonstrație, precum și obiectul introdus.


Pentru asta, mergeți mai departe și apăsați din nou butonul Adăugați date. Ar trebui să vedeți o eroare în consola:


Mesajul de eroare ar trebui să fie un indiciu. ConstraintError înseamnă că am încercat doar să adăugăm date cu aceeași cheie ca una deja existentă. Dacă vă amintiți, am codificat greu cheia și noi știut asta va fi o problemă. E timpul să discutăm cheile.


Chei

Cheile sunt versiunea indexedDB a cheilor primare. Bazele de date tradiționale pot avea tabele fără chei, dar fiecare magazin de obiecte trebuie să aibă o cheie. IndexedDB permite câteva tipuri diferite de chei.

Prima opțiune este să specificați-o singură, cum am făcut mai sus. Am putea folosi logica pentru a genera chei unice.

A doua opțiune este o cale cheie, unde cheia se bazează pe o proprietate a datelor în sine. Luați în considerare exemplul poporului nostru - am putea folosi o adresă de e-mail ca o cheie.

A treia opțiune și, după părerea mea, cea mai simplă este folosirea unui generator de chei. Aceasta funcționează la fel ca o cheie primară automată și este cea mai simplă metodă de specificare a cheilor.

Cheile sunt definite atunci când sunt create magazinele de obiecte. Iată două exemple - una utilizând o cale de cheie și una generatoare.

thisDb.createObjectStore ("test", keyPath: "email")); thisDb.createObjectStore ("test2", autoincrement: true);

Putem modifica demo-ul nostru anterior creând un magazin de obiecte cu o cheie de autoinstrumentare:

thisDB.createObjectStore ("oameni", autoIncrement: true);

În cele din urmă, putem să luăm apelul Adăugat anterior și să eliminăm codul greu codificat:

var request = store.add (persoană);

Asta e! Acum puteți adăuga date toată ziua. Puteți găsi această versiune în test7.html.


Citirea datelor

Acum, să treceți la citirea unor fragmente individuale de date (vom citi mai târziu citirea mai multor seturi de date). Încă o dată, acest lucru se va face într-o tranzacție și va fi asincron. Iată un exemplu simplu:

var tranzacție = db.transaction (["test"], "readonly"); var objectStore = transaction.objectStore ("test"); // x este o anumită valoare var ob = objectStore.get (x); ob.onsuccess = funcția (e) 

Rețineți că tranzacția este numai pentru citire. Apelul API este doar un apel simplu cu cheia trecuta inch. Pe scurt, dacă credeți că folosiți IndexedDB este un pic verbose, rețineți că puteți lanțuri multe dintre aceste apeluri, de asemenea. Iată exact același cod scrise mult mai stricte:

db.transaction (["test"], "readonly") obiectStore ("test") get (X) .insuccess =

Personal, încă mai găsesc IndexedDB un pic complex, așa că prefer modul de abordare "a ieșit din afară" pentru a mă ajuta să urmăresc ce se întâmplă.

Rezultatul procesului de preluare a succesului este obiectul pe care l-ați stocat înainte. Odată ce ai obiectul, poți să faci ce vrei. În următorul nostru demo (test8.html) am adăugat un câmp de formular simplu care vă permite să introduceți o cheie și să imprimați rezultatul. Iată un exemplu:


Handler-ul pentru butonul Get Data este de mai jos:

funcția getPerson (e) var key = document.querySelector ("# cheie"). dacă (key === "" || isNaN (key)) retur; var tranzacție = db.transaction (["oameni", "readonly"); var stoc = transaction.objectStore ("persoane"); var request = store.get (Număr (cheie)); request.onsuccess = funcție (e) var rezultat = e.target.result; console.dir (rezultat); dacă (rezultat) var s = "

Cheie "+ cheie +"

"pentru (câmp var în rezultat) s + = câmp +" = "+ rezultat [câmp] +"
" document.querySelector (" # status ") innerHTML = s; altceva document.querySelector (" # status ") innerHTML =

Nu se potrivesc

";

În cea mai mare parte, acest lucru ar trebui să fie explicativ. Obțineți valoarea din câmp și executați un apel la magazinul de obiecte obținut dintr-o tranzacție. Observați că codul de afișare devine pur și simplu toate câmpurile și le scot afară. Într-o aplicație reală, ați putea (sperăm) să știți ce conțin datele dvs. și să lucrați cu anumite domenii.


Citirea mai multor date

Deci așa vei obține o singură dată. Ce zici de a mult de date? IndexedDB are suport pentru ceea ce se numește un cursor. Un cursor vă permite să repetați datele. Puteți crea cursoare cu un interval opțional (un filtru de bază) și o direcție.

De exemplu, următorul bloc de coduri deschide un cursor pentru a prelua toate datele dintr-un magazin de obiecte. Ca orice altceva am făcut cu datele, aceasta este asincronă și într-o tranzacție.

var tranzacție = db.transaction (["test"], "readonly"); var objectStore = transaction.objectStore ("test"); var cursor = ObiectStore.openCursor (); cursor.onsuccess = funcție (e) var res = e.target.result; dacă (res) console.log ("Cheie", res.key); console.dir ("date", res.value); res.continue (); 

Operatorul de succes este trecut printr-un obiect rezultat (variabila res de mai sus). Acesta conține cheia, obiectul pentru date (în cheia de valoare de mai sus) și o metodă continuă care este utilizată pentru a itera către următoarea bucată de date.

În următoarea funcție, am folosit un cursor pentru a repeta toate datele de stocare a obiectelor. Deoarece lucrăm cu date personale pe care le-am denumit getPeople:

funcția getPeople (e) var s = ""; db.transaction (["people"], "readonly") ObiectStore ("people"). dacă (cursorul) s + = "

Cheie "+ cursor.key +"

"pentru (câmp var în cursor.value) s + = câmp +" = "+ cursor.value [câmp] +"
"; s + ="

"cursor.continue (); document.querySelector (" # status2 ") innerHTML = s;

Puteți vedea o demonstrație completă a acestui lucru în descărcarea dvs. ca fișier test9.html. Are logica Adăugați o persoană ca în exemplele anterioare, așa că creați doar câteva persoane și apoi apăsați butonul pentru a afișa toate datele.


Deci, acum știți cum să obțineți o singură dată, precum și cum să obțineți toate datele. Să urmărim acum subiectul nostru final - să lucrăm cu indicii.


Ei numesc acest indexedDB, corect?

Am vorbit despre IndexedDB pentru întregul articol, dar nu am făcut încă nici un indiciu bine. Indicii reprezintă o parte crucială a magazinelor de obiecte IndexedDB. Acestea oferă o modalitate de a prelua date pe baza valorii lor, precum și de a specifica dacă o valoare ar trebui să fie unică în cadrul unui magazin. Mai târziu, vom demonstra cum să folosim indexurile pentru a obține o gamă de date.

În primul rând, cum creați un index? Ca orice altceva structurale, ele trebuie facute intr-un eveniment de upgrade, practic, in acelasi timp in care creezi magazinul de obiecte. Iată un exemplu:

var objectStore = acestDb.createObjectStore ("oameni", autoIncrement: true); // primul arg este numele indexului, al doilea este calea (col); objectStore.createIndex ("nume", "nume", unic: fals); objectStore.createIndex ("email", "email", unic: true);

În prima linie vom crea magazinul. Luăm rezultatul (obiect objectStore) și execută createIndex metodă. Primul argument este numele indexului, iar al doilea este proprietatea care va fi indexată. În majoritatea cazurilor cred că veți folosi același nume pentru ambele. Argumentul final este un set de opțiuni. Pentru moment, folosim doar unul, unic. Primul index pentru nume nu este unic. Al doilea este pentru e-mail. Atunci când stocăm datele, IndexedDB va verifica acești indexuri și va asigura că proprietatea e-mailului este unică. Acesta va face, de asemenea, unele manipulare de date pe spate pentru a se asigura că putem prelua datele de către acești indici.

Cum funcționează? Odată ce ați preluat un magazin de obiecte printr-o tranzacție, puteți să solicitați un index din acel magazin. Folosind codul de mai sus, iată un exemplu:

var tranzacție = db.transaction (["oameni", "readonly"); var stoc = transaction.objectStore ("persoane"); var index = store.index ("nume"); // nume este o anumită valoare var request = index.get (nume);

Mai întâi primim tranzacția, urmată de magazin, apoi indexată. Așa cum am spus mai înainte, ați putea să alăturați primele trei linii pentru a deveni un pic mai compact dacă doriți.

Odată ce ați obținut un index, puteți efectua apoi obține apelați-l să preia datele după nume. Am putea face ceva similar și pentru e-mail. Rezultatul apelului respectiv este un alt obiect asincron pe care îl puteți lega de un handler onsuccess. Iată un exemplu de manipulator găsit în fișier test10.html:

request.onsuccess = funcție (e) var rezultat = e.target.result; dacă (rezultat) var s = "

Numele "+ nume +"

"pentru (câmp var în rezultat) s + = câmp +" = "+ rezultat [câmp] +"
" document.querySelector (" # status ") innerHTML = s; altceva document.querySelector (" # status ") innerHTML =

Nu se potrivesc

";

Rețineți că un index obține apelul poate returna mai multe obiecte. Întrucât numele nostru nu este unic, ar trebui probabil să modificăm codul pentru a face acest lucru, dar nu este necesar.

Acum hai să-i dăm o lovitură. Ați văzut folosirea interfeței API pe index pentru a obține o valoare bazată pe acea proprietate. Ce se întâmplă dacă doriți să obțineți un set mai larg de date? Termenul final pe care îl vom învăța astăzi este Ranges. Rangurile reprezintă o modalitate de a selecta un subset al unui index. De exemplu, dat fiind un index pe o proprietate de nume, putem folosi un interval pentru a găsi nume care încep cu A până la nume care încep cu C. Intervalele vin în câteva varietăți diferite. Ele pot fi "totul sub un anumit marker", "totul deasupra unui marker" și "ceva între un marcator inferior și un marker mai mare". În cele din urmă, doar pentru a face lucrurile interesante, intervalele pot fi incluzive sau exclusive. Practic înseamnă că pentru o gamă care merge de la A-C, putem specifica dacă vrem să includem A și C în intervalul sau doar valorile dintre ele. În cele din urmă, puteți solicita și gama ascendentă și descendentă.

Rangurile sunt create folosind un obiect toplevel numit IDBKeyRange. Are trei metode de interes: limita inferioară, limită superioară, și legat. limita inferioară este folosit pentru a crea o gamă care începe de la o valoare mai mică și returnează toate datele "deasupra" acesteia. limită superioară este opusul. Și, în sfârșit - legat este folosit pentru a suporta un set de date atât cu o limită inferioară cât și cu o limită superioară. Să ne uităm la câteva exemple:

// Valori peste 39 var oldRange = IDBKeyRange.lowerBound (39); Valori 40a dn peste var oldRange2 = IDBKeyRange.lowerBound (40, true); // 39 și mai mici ... var youngRange = IDBKeyRange.upperBound (40); // 39 și mai mici ... var youngRange2 = IDBKeyRange.upperBound (39, true); // nu tineri sau bătrâni ... puteți specifica inclusiv / exclusiv var okRange = IDBKeyRange.bound (20,40)

Odată ce aveți un interval, îl puteți transfera în metoda openCursor a unui index. Acest lucru vă oferă un iterator care să ocupe valorile care se potrivesc acelui interval. Ca o modalitate practică, aceasta nu este într-adevăr o căutare per se. Puteți folosi acest lucru pentru a căuta conținut pornind de la începutul unui șir, dar nu și mijlocul sau sfârșitul. Să ne uităm la un exemplu complet. Mai întâi vom crea o formulă simplă pentru a căuta persoane:

Incepand cu: 
Sfârșit cu:

Vom permite căutările care constau în oricare dintre cele trei tipuri de intervale (din nou o valoare și mai mare, o valoare mai mare sau valorile din două intrări). Acum hai să ne uităm la managerul evenimentului pentru acest formular.

funcția getPeople (e) var nume = document.querySelector ("# numeCăutare"); valoare; var endname = document.querySelector ("# numeSearchEnd") valoare; dacă (nume == "" && endname == "") retur; var tranzacție = db.transaction (["oameni", "readonly"); var stoc = transaction.objectStore ("persoane"); var index = store.index ("nume"); // Faceți intervalul în funcție de ce tip facem intervalul var; dacă (nume! = "" && endname! = "") range = IDBKeyRange.bound (nume, nume de nume);  altfel dacă (nume == "") range = IDBKeyRange.upperBound (nume de nume);  altceva range = IDBKeyRange.lowerBound (nume);  var s = ""; index.openCursor (intervalul) .onsuccess = funcția (e) var cursor = e.target.result; dacă (cursorul) s + = "

Cheie "+ cursor.key +"

"pentru (câmp var în cursor.value) s + = câmp +" = "+ cursor.value [câmp] +"
"; s + ="

"cursor.continue (); document.querySelector (" # status ") innerHTML = s;

De sus în jos - începem să luăm cele două câmpuri de formular. Apoi vom crea o tranzacție și din care vom obține magazinul și indexul. Acum, pentru partea semi-complexă. Deoarece avem trei tipuri diferite de intervale, trebuie să susținem că trebuie să facem un pic de logică condițională pentru a ne da seama de ce avem nevoie. Ce gama se creează se bazează pe câmpurile pe care le completezi. Ce este frumos este că, odată ce avem intervalul, vom trece apoi pur și simplu la index și vom deschide cursorul. Asta e! Puteți găsi acest exemplu în întregime test11.html. Asigurați-vă că introduceți mai întâi unele valori, astfel încât să aveți date de căutare.


Ce urmeaza?

Credeți sau nu - am început doar discuția noastră despre IndexedDB. În următorul articol, vom acoperi subiecte suplimentare, inclusiv actualizări și ștergeri, valori bazate pe matrice și câteva sfaturi generale pentru lucrul cu IndexedDB.

Cod