Trabajando con IndexedDB - Parte 2

Bienvenido a la segunda parte de mi artículo IndexedDB. yo fuertemente Recomiendo leer el primer artículo de esta serie, ya que supongo que está familiarizado con todos los conceptos tratados hasta ahora. En este artículo, vamos a resumir los aspectos de CRUD que no terminamos antes (específicamente actualizar y eliminar contenido), y luego demostraremos una aplicación del mundo real que usaremos para demostrar otros conceptos en el artículo final..


Actualización de registros

Comencemos discutiendo cómo actualizar un registro con IndexedDB. Si recuerdas, agregar datos fue bastante simple:

// Defina una persona var person = nombre: nombre, correo electrónico: correo electrónico, creado: nueva Fecha () // Realice la solicitud add var = store.add (person);

Actualizar un registro es igual de simple. Suponiendo que ha definido una propiedad llamada carné de identidad como su clave para su almacén de objetos, simplemente puede utilizar el poner método en lugar de añadir.

var person = nombre: nombre, correo electrónico: correo electrónico, creado: new Date (), id: someId // Realizar la actualización var request = store.put (person);

Como el añadir método, puede asignar métodos para manejar los resultados asíncronos de la operación.


Borrar registros

La eliminación de registros se realiza a través del método de eliminación. (Gran sorpresa allí). Simplemente pase el identificador único del registro que desea eliminar. Aquí hay un ejemplo simple:

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

Y como cualquier otro aspecto de IndexedDB, puede agregar sus controladores para los resultados asíncronos.

Entonces, como dije, no es terriblemente emocionante, lo que probablemente sea bueno. Desea que sus API sean simples, aburridas y sorprendentes. Ahora tomemos lo que hemos aprendido y juntémoslo para crear una aplicación real, aunque simple..


La aplicación Note

Ok, finalmente tenemos todas (bueno, la mayoría) de las partes que necesitamos para construir una aplicación real. Como no se ha hecho antes (Ejem), vamos a construir una aplicación simple para tomar notas. Veamos algunas capturas de pantalla y luego te mostraré el código que hay detrás. Al iniciarse, la aplicación inicializa un IndexedDB para la aplicación y presenta una tabla vacía. Inicialmente, todo lo que puedes hacer con la aplicación es agregar una nueva nota. (Podríamos hacer esto un poco más fácil de usar, tal vez).


Haciendo clic en el Añadir la nota botón abre un formulario:


Después de ingresar algunos datos en el formulario, puede guardar la nota:


Como puede ver, tiene la opción de editar y eliminar notas. Finalmente, si hace clic en la fila, puede leer la nota:


Así que no es exactamente la ciencia espacial, sino un ejemplo completo de la especificación de IndexedDB. Las notas escritas aquí persistirán. Puede cerrar su navegador, reiniciar su máquina, tomarse unos años para contemplar la vida y la poesía, y cuando vuelva a abrir el navegador, sus datos todavía estarán allí. Echemos un vistazo al código ahora.

Primero - un descargo de responsabilidad. Esta aplicación hubiera sido un candidato perfecto para uno de los muchos marcos de JavaScript. Estoy seguro de que aquellos de ustedes que usan Backbone o Angular ya pueden imaginar cómo configurarían esto. Sin embargo, he tomado la decisión audaz aquí no utilizar un marco. Estaba preocupado tanto por las personas que pueden usar un marco diferente como por las que no usan ninguno. Quería que nuestro enfoque aquí estuviera solo en los aspectos de IndexedDB. Espero totalmente que algunas personas no estén de acuerdo con esa decisión, pero vamos a analizarla en los comentarios..

Nuestra primera plantilla es el archivo HTML. Solo tenemos uno y la mayor parte es repetitivo:

     Base de datos de notas     
Base de datos de notas

Editar nota

Como se mencionó anteriormente, una buena parte del tamaño de este archivo es el código de plantilla para Bootstrap. Las partes que nos importan son las notaLista div, el noteDetail div, y el notaForm. Probablemente pueda adivinar que estos son los DIV que actualizaremos a medida que el usuario haga clic en la aplicación..

Codificando nuestro archivo de aplicación principal

Ahora echemos un vistazo a app.js, El archivo central que maneja la lógica de nuestra aplicación..

/ * consola global, $, documento, ventana, alerta * / var db; función dtFormat (entrada) si (! entrada) devuelve ""; var res = (input.getMonth () + 1) + "/" + input.getDate () + "/" + input.getFullYear () + ""; var hora = input.getHours (); var ampm = "AM"; if (hour === 12) ampm = "PM"; si (hora> 12) hora- = 12; ampm = "PM";  var minute = input.getMinutes () + 1; si < 10) minute = "0" + minute; res += hour + ":" + minute + " " + ampm; return res; 

Puede ignorar la primera función, ya que es simplemente una utilidad de formato para fechas. Vayamos al bloque de documentos listos para jQuery..

Comprobando el soporte del navegador

 $ (document) .ready (function () if (! ("indexedDB" en la ventana)) alert ("¡Se requiere el soporte de IndexedDB para esta demostración!"); return; var $ noteDetail = $ ("# noteDetail") ; var $ noteForm = $ ("# noteForm"); var openRequest = window.indexedDB.open ("nettuts_notes_1", 1); openRequest.onerror = function (e) console.log ("Error abriendo db"); console .dir (e);; openRequest.onupgradeneeded = function (e) var thisDb = e.target.result; var objectStore; // Crear un sistema operativo Note si (! thisDb.objectStoreNames.contains ("note")) console .log ("Necesito hacer el almacén de objetos de la nota"); objectStore = thisDb.createObjectStore ("note", keyPath: "id", autoIncrement: true);; openRequest.onsuccess = function (e) db = e.target.result; db.onerror = function (event) // Controlador genérico de errores para todos los errores dirigidos a las // pedidos! alert de esta base de datos ("Error de la base de datos:" + event.target.errorCode); console.dir (event.target);; displayNotes ();;

Nuestra primera acción es verificar la compatibilidad con IndexedDB. Si el navegador del usuario no es compatible, utilizamos una alerta y abortamos la función. Probablemente sería mejor reubicarlos en una página que explique por qué no pueden usar la aplicación. (Y para ser claros, también podríamos crear una aplicación que hiciera uso de WebSQL como respaldo. Pero nuevamente, mi enfoque aquí es la simplicidad).

Después de almacenar algunos selectores de jQuery, que utilizaremos en toda la aplicación, abriremos nuestra base de datos IndexedDB. La base de datos es bastante simple. En el onupgradeneeded controlador se puede ver un almacén de objetos llamado notas siendo creado. Una vez hecho todo, el éxito manejador disparará una llamada a displayNotes.

los displayNotes Función

 función displayNotes () var transaction = db.transaction (["note"], "readonly"); contenido var = ""; transaction.oncomplete = function (event) $ (" # noteList "). html (content);; var handleResult = function (event) var cursor = event.target.result; if (cursor) content + = ""; content + =""; content + =""; content + =""; cursor.continue (); else content + ="
TítuloActualizado 
"+ cursor.value.title +""+ dtFormat (cursor.value.updated) +"Editar Borrar
";; var objectStore = transaction.objectStore (" note "); objectStore.openCursor (). onsuccess = handleResult;

los displayNotes La función hace lo que usted espera: obtenga todos los datos y visualícelos. Discutimos cómo obtener todas las filas de datos en la entrada anterior, pero quiero señalar algo ligeramente diferente sobre este ejemplo. Tenga en cuenta que tenemos un nuevo controlador de eventos, incompleto, que hemos atado a la transacción en sí. Anteriormente, hemos usado eventos solo dentro de las acciones., dentro La transacción, pero IndexedDB nos permite hacerlo también en el nivel superior. Esto se vuelve especialmente útil en un caso como este. Tenemos una cadena gigante, nuestra tabla HTML, que construimos sobre cada iteración de nuestros datos. Podemos utilizar la transacción de incompleto controlador para envolver la parte de la pantalla y escribirla usando una simple llamada jQuery.

los Borrar, Editar, y Añadir Funciones

 $ ("# noteList"). on ("click", "a.delete", function (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 ();; return false;); $ ("# noteList"). en ("click", "a.edit", function (e) var thisId = $ (this) .parent (). parent (). data ("key"); solicitud de var = 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 (); ; falso retorno; ); $ ("# noteList"). en ("click", "td", function () var thisId = $ (this) .parent (). data ("key"); var transaction = db.transaction ([" note "]); var objectStore = transaction.objectStore (" note "); var request = objectStore.get (thisId); request.onsuccess = function (event) var note = request.result; $ noteDetail.html ("

"+ nota.título +"

"+ note.body +"

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

Nuestros siguientes dos métodos (borrar y editar) es otro ejemplo de este mismo principio. Como ninguna de las llamadas de IndexedDB aquí son nuevas, no nos molestaremos en revisarlas. La mayor parte de la "carne" aquí termina siendo una simple manipulación de DOM para manejar las acciones particulares. El controlador para hacer clic en el botón Agregar es exactamente eso, por lo que también lo omitiremos.

los Salvar Función

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

El siguiente dato interesante es el salvar método. Tiene que usar un poco de lógica para determinar si estamos agregando o actualizando, pero incluso eso es bastante simple. ¡Y eso es! Una aplicación completa, aunque simple, IndexedDB. Puedes jugar con esta demo descargando el código fuente adjunto.


En conclusión

Eso es todo por la segunda parte! El tercer artículo tomará esta aplicación y comenzará a agregar características adicionales, incluidas la búsqueda y las propiedades basadas en matrices..