2012-10-04 17 views
6

Estoy trabajando en una aplicación web habilitada sin conexión. Estoy usando Backbone.js para el código del cliente. Necesito backbone.js para cambiar entre el servidor remoto y el IndexedDB local de acuerdo con el estado en línea/fuera de línea del usuario. ¿Cuál de las siguientes formas es la forma correcta de hacerlo:Uso de IndexedDB y del servidor remoto con Backbone.js

  1. Utilice este indexeddb-backbone adapter por superfeedr. Pero creo que atiende mejor el almacenamiento fuera de línea y no tanto fuera de línea como en línea.
  2. Reemplace el método sync() en backbone.js y, por lo tanto, cree su propio adaptador específico de necesidades.
+0

Muy interesante. Puede ser que la aplicación use IndexedDB directamente y permita que el derivador IndexedDB se sincronice con el servidor. Si hay algún conflicto, el contenedor debería enviar el evento actualizado. Esto simplificará cada rol. –

+0

@KyawTun gracias, ¡esto parece un buen diseño! Pero cualquiera que sea el diseño que se me ocurra, necesitaría backbone.js para comunicarme con IndexedDB y el servidor remoto. Mi pregunta es ¿cuál de las dos formas mencionadas en mi post es la mejor manera de hacerlo. – shreyj

Respuesta

5

Déjame dar una sesión. Nunca uso backbone.js. Sin embargo, tengo el impresionante contenedor IndexedDB YDB-DB y tengo previsto respaldar los frameworks vinculantes de backbone.js y angular.js. Pero parece que no hay mucho que hacer.

Como se sugirió el interrogador, el patrón de adaptador de anulación Backbone.sync(method, model, options) es posible con poca lógica adicional con la biblioteca contenedora de la base de datos.

Backbone.sync esperan que el objeto de retorno sea el objeto jqXHR, que implementa Promise interface. Backbone.sync se sobrescribe para intersectarse para el almacenamiento en caché en la base de datos del lado del cliente. Un proveedor de fuente de datos, $.db, se establece un esquema correspondiente al modelo dado. (Véase la YDN-DB para más detalles.) Espero que el servidor back-end de Google acepta datos del modelo GData-como entrada (Atom), en el que cada modelo tiene atributo etag y resolución de conflictos optimistas se utiliza.

$.db = new ydn.db.Storage('db_name', schema); 

var Backbone_sync = Backbone.sync; 
Backbone.sync = function(method, model, options) { 
    var df = $.Deferred(); 
    if (method == 'read') { 
    var df_db = $.db.get(model.name, model.cid); 
    df_db.done(function(data) { 
     if (data) { 
     df.resolve(data); 
     options['header'].push({'If-Not-Match': data.etag}); 
     var ajax_df = Backbone_sync(method, model, options); 
     ajax_df.done(function(new_data) { 
      if (new_data) { 
      assert(new_data.cid == model.cid); 
      $.db.put(model.name, new_data); 
      model.set(new_data).change(); 
      } // else, no change 
     }); 
     } else { 
     var ajax_df = Backbone_sync(method, model, options); 
     df.pipe(ajax_df); 
     ajax_df.done(function(new_data) { 
      $.db.put(model.name, new_data); 
     }); 
     } 
    }); 
    df_db.fail(function(e) { 
     throw e; // db connection blocking, or schema mismatch 
    }); 
    } else if (method == 'update') { 
    options['header'].push({'If-Match': model.etag}); 
    var ajax_df = Backbone_sync(method, model, options); 
    df.pipe(ajax_df); 
    ajax_df.done(function(new_data, status) { 
     if (status == 409) { // conflict 
     assert(new_data.cid == model.cid); 
     $.db.run(function(db) { // run in transaction 
      db.get(model.name, model.cid).done(function(data) { // NOTE: not $.db 
      if (data) { 
       var resolved_data = $.magic.resolve(new_data, data); 
       db.put(model.name, resolved_data); 
       model.set(resolved_data);    
       model.save(); // send merge result to server     
      } else { 
       db.put(model.name, new_data); 
      } 
      }); 
     }, model.name, 'readwrite'); // transaction scope of model object store for read write operations 
     } else if (status == 404) { // not found 
     $db.clear(model.name, model.cid); 
     } else if (status < 300) { 
     assert(new_data.cid == model.cid); 
     $.db.put(model.name, new_data); 
     } 
    }); 
    } 

    return df; 
}; 

Los métodos restantes se pueden implementar de manera similar. Las colecciones y las consultas también pueden cruzarse y suministrarse desde la memoria caché de la base de datos.

Si el servidor no implementa etag, que queda trabajo, pero no te ahorrar ancho de banda del servidor, ni resolver los conflictos.

Cuestiones relacionadas