domingo, 15 de mayo de 2016

Listando datos con HTML, CSS y JavaScript



El método get() implementado en el código 11-7 solo retorna un objeto por vez (el último insertado). En el siguiente ejemplo vamos a usar un cursor para generar una lista incluyendo todas las películas almacenadas en el Almacén de Objetos peliculas.

Cursores

Los cursores son una alternativa ofrecida por la API para obtener y navegar a través de un grupo de objetos encontrados en la base de datos. Un cursor obtiene una lista específica de objetos de un Almacén de Objetos e inicia un puntero que apunta a un objeto de la lista a la vez.
Para generar un cursor, la API provee el método openCursor(). Este método extrae información del Almacén de Objetos seleccionado y retorna un objeto IDBCursor que tiene sus propios atributos y métodos para manipular el cursor:
  • continue() Este método mueve el puntero del cursor una posición y el evento success del cursor es disparado nuevamente. Cuando el puntero alcanza el final de la lista, el evento success es también disparado, pero retorna un objeto vacío. El puntero puede ser movido a una posición específica declarando un valor de índice dentro de los paréntesis.
  • delete() Este método elimina el objeto en la posición actual del cursor.
  • update(valor) Este método es similar a put() pero modifica el valor del objeto en la posición actual del cursor.

El método openCursor() también tiene atributos para especificar el tipo de objetos retornados y su orden. Los valores por defecto retornan todos los objetos disponibles en el Almacén de Objetos seleccionado, organizados en orden ascendente. Estudiaremos este tema más adelante.

Código 11-9. Lista de objetos.

function iniciar(){
cajadatos=document.getElementById('cajadatos');
var boton=document.getElementById('grabar');
boton.addEventListener('click', agregarobjeto, false);
if('webkitIndexedDB' in window){
window.indexedDB=window.webkitIndexedDB;
window.IDBTransaction=window.webkitIDBTransaction;
window.IDBKeyRange=window.webkitIDBKeyRange;
window.IDBCursor=window.webkitIDBCursor;
}else if('mozIndexedDB' in window){
window.indexedDB=window.mozIndexedDB;
}
var solicitud=indexedDB.open('mibase');
solicitud.addEventListener('error', errores, false);
solicitud.addEventListener('success', crear, false);
}
function errores(e){
alert('Error: '+e.code+' '+e.message);
}
function crear(e){
bd=e.result || e.target.result;
if(bd.version==''){
var solicitud=bd.setVersion('1.0');
solicitud.addEventListener('error', errores, false);
solicitud.addEventListener('success', crearbd, false);
}else{
mostrar();
}
}
function crearbd(){
var almacen=bd.createObjectStore('peliculas',{keyPath: 'id'});
almacen.createIndex('BuscarFecha', 'fecha',{unique: false});
}
function agregarobjeto(){
var clave=document.getElementById('clave').value;
var titulo=document.getElementById('texto').value;
var fecha=document.getElementById('fecha').value;
var transaccion=bd.transaction(['peliculas'],
IDBTransaction.READ_WRITE);
var almacen=transaccion.objectStore('peliculas');
var solicitud=almacen.add({id: clave, nombre: titulo, fecha:
fecha});
solicitud.addEventListener('success', mostrar, false);
document.getElementById('clave').value='';
document.getElementById('texto').value='';
document.getElementById('fecha').value='';
}
function mostrar(){
cajadatos.innerHTML='';
var transaccion=bd.transaction(['peliculas']);
var almacen=transaccion.objectStore('peliculas');
var cursor=almacen.openCursor();
cursor.addEventListener('success', mostrarlista, false);
}
function mostrarlista(e){
var cursor=e.result || e.target.result;
if(cursor){
cajadatos.innerHTML+='<div>'+cursor.value.id+' -
'+cursor.value.nombre+' - '+cursor.value.fecha+'</div>';
cursor.continue();
}
}
window.addEventListener('load', iniciar, false);

El Código 11-9 muestra el código Javascript completo que necesitamos para este ejemplo. De las funciones usadas para configurar la base de datos, solo crear() presenta un pequeño cambio. Ahora, cuando la versión de la base de datos sea diferente a null (lo que significa que la base de datos ya ha sido creada) la función mostrar() es ejecutada. 
Esta función ahora se encuentra a cargo de mostrar la lista de objetos almacenados en el Almacén de Objetos, por lo que si la base de datos ya existe veremos una lista de objetos en la caja derecha de la pantalla tan pronto como la página web es cargada. 
La mejora introducida en este código se encuentra en las funciones mostrar() y mostrarlista(). Aquí es donde trabajamos con cursores por primera vez.
Leer información de la base de datos con un cursor es también una operación que debe hacerse a través de una transacción. Por este motivo, lo primero que hacemos en la función mostrar() es generar una transacción del tipo READ_ONLY sobre el Almacén de Objetos peliculas. Este Almacén de Objetos es seleccionado como el involucrado en la transacción y luego el cursor es abierto sobre este almacén usando el método openCursor().
Si la operación es exitosa, un objeto es retornado con toda la información obtenida del Almacén de Objetos, un evento success es disparado desde este objeto y la función mostrarlista() es ejecutada.
Para leer la información, el objeto retornado por la operación ofrece varios atributos: 
  • key Este atributo retorna el valor de la clave del objeto en la posición actual del cursor. 
  • value Este atributo retorna el valor de cualquier propiedad del objeto en la posición actual del cursor. El nombre de la propiedad debe ser especificado como una propiedad del atributo (por ejemplo, value.fecha).
  • direction Los objetos pueden ser leídos en orden ascendente o descendente (como veremos más adelante); este atributo retorna la condición actual en la cual son leídos. 
  • count Este atributo retorna en número aproximado de objetos en el cursor.

En la función mostrarlista() del Código 11-9, usamos el condicional if para controlar el contenido del cursor. Si ningún objeto es retornado o el puntero alcanza el final de la lista, entonces el objeto estará vacío y el bucle no es continuado. Sin embargo, cuando el puntero apunta a un objeto válido, la información es mostrada en pantalla y el puntero es movido hacia la siguiente posición con continue().
Es importante mencionar que no debemos usar un bucle while aquí debido a que el método continue() dispara nuevamente el evento success del cursor y la función completa es ejecutada para leer el siguiente objeto retornado.
Hágalo usted mismo: El código 11-9 reemplaza todos los códigos Javascript previos. Vacíe el archivo indexed.js y copie en su interior este nuevo código. Abra la plantilla del Código 11-1 y, si aún no lo hizo, inserte todas las películas del código encontrado al comienzo de este capítulo. Verá la lista completa de películas en la caja derecha de la pantalla en orden ascendente, de acuerdo al valor de la propiedad id.

Cambio de orden

Hay dos detalles que necesitamos modificar para obtener la lista que queremos. Todas las películas en nuestro ejemplo están listadas en orden ascendente y la propiedad usada para organizar los objetos es id. Esta es la propiedad declarada como el atributo clave cuando el Almacén de Objetos peliculas fue creado, y es por tanto el índice usado por defecto. Pero ésta clase de valores no es lo que a nuestros usuarios normalmente les interesa. 
Considerando esta situación, creamos otro índice en la función crearbd(). El nombre de este índice adicional fue declarado como BuscarFecha y la propiedad asignada al mismo es fecha. Este índice nos permitirá ordenar las películas de acuerdo al valor del año en el que fueron filmadas.

Código 11-10. Orden descendiente por año.

function mostrar(){
cajadatos.innerHTML='';
var transaccion=bd.transaction(['peliculas']);
var almacen=transaccion.objectStore('peliculas');
var indice=almacen.index('BuscarFecha');
var cursor=indice.openCursor(null, IDBCursor.PREV);
cursor.addEventListener('success', mostrarlista, false);
}

La función en el Código 11-10 reemplaza a la función mostrar() del código 11-9. Esta nueva función genera una transacción, luego asigna el índice BuscarFecha al Almacén de Objetos usado en la transacción, y finalmente usa openCursor() para obtener los objetos que tienen la propiedad correspondiente al índice (en este caso fecha).

Existen dos atributos que podemos especificar en openCursor() para seleccionar y ordenar la información obtenida por el cursor. El primer atributo declara el rango dentro del cual los objetos serán seleccionados y el segundo es una de las siguientes constantes:
  • NEXT (siguiente). El orden de los objetos retornados será ascendente (este es el valor por defecto).
  • NEXT_NO_DUPLICATE (siguiente no duplicado). El orden de los objetos retornados será ascendente y los objetos duplicados serán ignorados (solo el primer objeto es retornado si varios comparten el mismo valor de índice).
  • PREV (anterior). El orden de los objetos retornados será descendente. 
  • PREV_NO_DUPLICATE (anterior no duplicado). El orden de los objetos retornados será descendente y los objetos duplicados serán ignorados (solo el primer objeto es retornado si varios comparten el mismo valor de índice).

Con el método openCursor() usado en la función mostrar() en el Código 11-10, obtenemos los objetos en orden descendente y declaramos el rango como null. Vamos a aprender cómo construir un rango y retornar solo los objetos deseados más adelante en este capítulo.
Hágalo usted mismo: Tome el código anterior presentado en el Código 11-9 y reemplace la función show() con la nueva función del Código 11-10. Esta nueva función lista las películas en la pantalla por año y en orden descendente (las más nuevas primero). El resultado debería ser el siguiente: 
id: tt1285016 nombre: La Red Social fecha: 2010
id: tt0111161 nombre: Cadena Perpetua fecha: 1994
id: tt0086567 nombre: Juegos de Guerra fecha: 1983
id: tt0068646 nombre: El Padrino fecha: 1972



Espero haber ayudado en algo. Hasta la próxima oportunidad!











  

No hay comentarios:

Publicar un comentario en la entrada