2012-10-04 13 views
6

Pracuję nad aplikacją internetową obsługującą tryb offline. Używam Backbone.js do kodu klienta. Potrzebuję backbone.js, aby przełączać się między serwerem zdalnym a lokalnym IndexedDB zgodnie ze stanem online/offline użytkownika. Który z poniższych sposobów jest właściwy:Korzystanie z IndexedDB oraz serwera zdalnego za pomocą narzędzia Backbone.js

  1. Użyj tego indexeddb-backbone adapter przez superfeedr. Ale uważam, że bardziej zależy mu na przechowywaniu w trybie offline, a nie w trybie offline i online.
  2. Zastąp metodę sync() w backbone.js, a tym samym utwórz własny adapter.
+0

Bardzo interesujące. Może to być aplikacja bezpośrednio korzystająca z IndexedDB i pozwalająca na zsynchronizowanie wrappera IndexedDB z serwerem. W przypadku jakiegokolwiek konfliktu, opakowanie powinno wysłać zaktualizowane zdarzenie. Uprości to każdą rolę. –

+0

@KyawTun dzięki, to wydaje się dobry projekt! Ale niezależnie od tego, jaki projekt wymyślę, potrzebowałabym backbone.js do komunikowania się zarówno z IndexedDB, jak iz serwerem zdalnym. Moje pytanie brzmi, który z dwóch sposobów wymienionych w moim poście to lepszy sposób na zrobienie tego. – shreyj

Odpowiedz

5

Pozwól mi dać zdjęcie. Nigdy nie użyłem backbone.js. Mam jednak niesamowitą wrappera IndexedDB YDB-DB i planuję wspierać szkielety szkieletów backbone.js i angular.js. Ale wydaje się, że niewiele do zrobienia.

Zgodnie z pytaniem, wzorzec adaptera nadpisującego Backbone.sync(method, model, options) jest możliwy z kilkoma dodatkowymi logikami z biblioteką otoki bazy danych.

Backbone.sync oczekiwać, że obiekt powrotu będzie obiektem jqXHR, który implementuje Promise interface. Backbone.sync jest nadpisany do przecięcia dla buforowania w bazie danych po stronie klienta. Dostawca źródła danych, $.db, jest ustawiony w schemacie odpowiadającym danemu modelowi. (Zobacz więcej szczegółów w YDN-DB.) Oczekuję, że serwer zaplecza zaakceptuje dane modelu podobnego do Google GData (Atom Entry), w którym każdy model ma atrybut etag i optymistyczne rozwiązanie konfliktu.

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

Pozostałe metody można realizować w podobny sposób. Kolekcje i zapytania mogą również przecinać się i dostarczać z pamięci podręcznej bazy danych.

Jeśli serwer nie implementuje etag, to nadal działa, ale użytkownik nie będzie oszczędzać przepustowości serwera ani rozwiązywać konfliktów.

Powiązane problemy