Using IndexedDB as well as Remote Server with Backbone.js

I am working on a standalone web application. I am using Backbone.js for client code. I need backbone.js to switch between the remote server and the local index according to the online state of the user. Which of the following methods is the correct way to do this:

  • Use this indexeddb-backbone adapter with superfeedr. But I feel that it is more suitable for offline storage, rather than both offline and online.
  • Override the sync () method in backbone.js and therefore create your own specific adapter.
+6
source share
1 answer

Let me give a shot. I have never used backbone.js. However, I have an awesome IndexedDB YDB-DB wrapper, and I plan on supporting backbone.js and angular.js bindings. But that is not so much.

As the survey suggested, the Backbone.sync(method, model, options) override adapter template is possible with several additional logics with a database wrapper library.

Backbone.sync expect the returned object to be a jqXHR object that implements the Promise interface . Backbone.sync overridden for traversal for caching in the client database. The $.db data source provider has been assigned a schema that matches this model. (See YDN-DB for more details.) I expect the backend server to accept model data similar to the Google GData (Atom Entry) model, in which each model has an etag attribute and optimistic conflict resolution.

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

Other methods can be implemented in a similar way. Collections and query can also intersect and ship from the database cache.

If the server does not implement etag, it still works, but you will not save the server bandwidth and resolve the conflict.

+5
source

Source: https://habr.com/ru/post/926922/


All Articles