/**
* Backbone localStorage Adapter
* Version 1.1.0
*
* https://github.com/jeromegn/Backbone.localStorage
*/
(function (root, factory) {
if (typeof define === "function" && define.amd) {
/**
* Backbone localStorage Adapter
* Version 1.1.0
*
* https://github.com/jeromegn/Backbone.localStorage
*/
(function (root, factory) {
if (typeof define === "function" && define.amd) {
作为匿名模块注册 AMD。
define(["underscore","backbone"], function(_, Backbone) {
如果本地变量未定义,则使用全局变量。
return factory(_ || root._, Backbone || root.Backbone);
});
} else {
未使用 RequireJS。假设 underscore 和 backbone 在脚本标签中加载。
factory(_, Backbone);
}
}(this, function(_, Backbone) {
一个简单的模块,用localStorage 驱动的持久化替换 Backbone.sync
。模型被赋予 GUID,并保存到 JSON 对象中。就这么简单。
在闭包中保存对 Underscore.js 和 Backbone.js 的引用,以便即使它们从全局命名空间中删除也能正常工作。
生成四个随机十六进制数字。
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
通过连接随机十六进制数生成伪 GUID。
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};
我们的存储由localStorage 中的单个 JS 对象表示。使用有意义的名称创建它,就像你给表格起的名字一样。window.Store 已被弃用,请使用 Backbone.LocalStorage 代替。
Backbone.LocalStorage = window.Store = function(name) {
this.name = name;
var store = this.localStorage().getItem(this.name);
this.records = (store && store.split(",")) || [];
};
_.extend(Backbone.LocalStorage.prototype, {
将Store 的当前状态保存到localStorage。
save: function() {
this.localStorage().setItem(this.name, this.records.join(","));
},
添加一个模型,如果它还没有自己的 id,则赋予它一个(希望是)唯一的 GUID。
create: function(model) {
if (!model.id) {
model.id = guid();
model.set(model.idAttribute, model.id);
}
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
this.records.push(model.id.toString());
this.save();
return this.find(model);
},
通过替换 this.data
中的副本更新模型。
update: function(model) {
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
if (!_.include(this.records, model.id.toString()))
this.records.push(model.id.toString()); this.save();
return this.find(model);
},
通过 id 从 this.data
中检索模型。
find: function(model) {
return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
},
返回当前存储中所有模型的数组。
findAll: function() {
return _(this.records).chain()
.map(function(id){
return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
}, this)
.compact()
.value();
},
从 this.data
中删除一个模型,并返回它。
destroy: function(model) {
if (model.isNew())
return false
this.localStorage().removeItem(this.name+"-"+model.id);
this.records = _.reject(this.records, function(id){
return id === model.id.toString();
});
this.save();
return model;
},
localStorage: function() {
return localStorage;
},
修复 Android 上 JSON.parse 传递 null 时出现的“非法访问”错误。
jsonData: function (data) {
return data && JSON.parse(data);
}
});
localSync 代理到模型或集合的localStorage 属性,该属性应该是 Store
的实例。window.Store.sync 和 Backbone.localSync 已被弃用,请使用 Backbone.LocalStorage.sync 代替。
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
var store = model.localStorage || model.collection.localStorage;
var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.
try {
switch (method) {
case "read":
resp = model.id != undefined ? store.find(model) : store.findAll();
break;
case "create":
resp = store.create(model);
break;
case "update":
resp = store.update(model);
break;
case "delete":
resp = store.destroy(model);
break;
}
} catch(error) {
if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0)
errorMessage = "Private browsing is unsupported";
else
errorMessage = error.message;
}
if (resp) {
model.trigger("sync", model, resp, options);
if (options && options.success)
options.success(resp);
if (syncDfd)
syncDfd.resolve(resp);
} else {
errorMessage = errorMessage ? errorMessage
: "Record Not Found";
if (options && options.error)
options.error(errorMessage);
if (syncDfd)
syncDfd.reject(errorMessage);
}
添加对 $.ajax 始终执行成功和错误回调的兼容性。
if (options && options.complete) options.complete(resp);
return syncDfd && syncDfd.promise();
};
Backbone.ajaxSync = Backbone.sync;
Backbone.getSyncMethod = function(model) {
if(model.localStorage || (model.collection && model.collection.localStorage)) {
return Backbone.localSync;
}
return Backbone.ajaxSync;
};
覆盖 ‘Backbone.sync’ 以默认使用 localSync,原始的 ‘Backbone.sync’ 仍然可以在 ‘Backbone.ajaxSync’ 中使用。
Backbone.sync = function(method, model, options) {
return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
};
return Backbone.LocalStorage;
}));