alloy
Version:
TiDev Titanium MVC Framework
101 lines (79 loc) • 2.13 kB
JavaScript
/*
* HTML5 localStorage sync adapter
*/
var _ = require('/alloy/underscore')._;
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
function guid() {
return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4());
}
function InitAdapter() {
if (!OS_MOBILEWEB) {
throw 'localStorage persistence supported only with MobileWeb.';
}
}
function Sync(method, model, opts) {
var name = model.config.adapter.collection_name,
data = model.config.data,
resp = null;
function storeModel(data) {
localStorage.setItem(name, JSON.stringify(data));
}
switch (method) {
case 'create':
if (!model.id) {
model.id = guid();
model.set(model.idAttribute, model.id);
}
data[model.id] = model;
storeModel(data);
resp = model.toJSON();
break;
case 'read':
var store = localStorage.getItem(name);
var store_data = (store && JSON.parse(store)) || {};
var len = 0;
for (var key in store_data) {
var m = new model.config.Model(store_data[key]);
model.models.push(m);
len++;
}
model.length = len;
if (len === 1) {
resp = model.models[0];
} else {
resp = model.models;
}
break;
case 'update':
data[model.id] = model;
storeModel(data);
resp = model.toJSON();
break;
case 'delete':
delete data[model.id];
storeModel(data);
resp = model.toJSON();
break;
}
// process success/error handlers, if present
if (resp) {
if (_.isFunction(opts.success)) { opts.success(resp); }
if (method === 'read') { model.trigger('fetch'); }
} else {
if (_.isFunction(opts.error)) { opts.error(resp); }
}
}
module.exports.sync = Sync;
module.exports.beforeModelCreate = function(config) {
config = config || {};
config.data = {}; // for localStorage or case where entire collection is needed to maintain store
InitAdapter();
return config;
};
module.exports.afterModelCreate = function(Model) {
Model = Model || {};
Model.prototype.config.Model = Model; // needed for fetch operations to initialize the collection from persistent store
return Model;
};