2012-10-04 15 views
6

Sto lavorando a un'app Web con funzionalità offline. Sto usando Backbone.js per il codice client. Ho bisogno di backbone.js per passare tra server remoto e IndexedDB locale in base allo stato online/offline dell'utente. Quale dei seguenti modi è il modo giusto per farlo:Utilizzo di IndexedDB e server remoto con Backbone.js

  1. Utilizzare questo indexeddb-backbone adapter per superfeedr. Ma sento che si rivolge di più allo storage offline e non sia offline che online.
  2. Sostituire il metodo sync() in backbone.js e quindi creare il proprio adattatore specifico.
+0

Molto interessante. L'app può essere utilizzata direttamente IndexedDB e lasciare che il wrapper IndexedDB si sincronizzi con il server. In caso di conflitto, il wrapper deve inviare l'evento aggiornato. Questo semplificherà ogni ruolo. –

+0

@KyawTun grazie, questo sembra un buon design! Ma qualunque sia il design che mi viene in mente, avrei bisogno di backbone.js per comunicare con IndexedDB e il server remoto. La mia domanda è quale dei due modi menzionati nel mio post è il modo migliore per farlo. – shreyj

risposta

5

Lasciami fare uno scatto. Non ho mai usato backbone.js. Tuttavia, ho un fantastico wrapper IndexedDB YDB-DB e ho intenzione di supportare i framework di binding backbone.js e angular.js. Ma non sembra molto da fare.

Come suggerito da un interlocutore, il modello di adattatore di override Backbone.sync(method, model, options) è possibile con poca logica aggiuntiva con la libreria del wrapper del database.

Backbone.sync si aspetta che l'oggetto di ritorno sia l'oggetto jqXHR, che implementa Promise interface. Backbone.sync è stato interrotto per intersecarsi per la memorizzazione nella cache nel database lato client. Un provider di origini dati, $.db, imposta uno schema corrispondente al modello specificato. (Vedi il YDN-DB per maggiori dettagli.) Mi aspetto che il server backend accetti i dati del modello di Google GData (Atom Entry), in cui ogni modello ha un attributo etag e viene utilizzata una risoluzione ottimistica del conflitto.

$.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; 
}; 

I metodi rimanenti possono essere implementati in modo simile. Le raccolte e le query possono anche intersecare e fornire dalla cache del database.

Se il server non implementa etag, è ancora funzionante, ma non si risparmia la larghezza di banda del server né si risolve il conflitto.

Problemi correlati