关注Backbone已经有一年多了,终于有机会在近期的项目中使用其进行重构,接下来记录一些学习笔记和使用心得,希望和大家进行交流,共同提高。
Backbone的命名空间和冲突管理
首先Backbone包含一个会立即执行的函数表达式:
(function(){ // Backbone.js }).call(this);
接下来,它配置一个叫Backbone命名空间,并通过noConflict模式来解决多个Backbone版本的冲突问题
var root = this; var previousBackbone = root.Backbone; Backbone.noConflict = function() { root.Backbone = previousBackbone; return this; };
这样在同一个页面中的多个backbone版本就可以象下面这样调用了
var Backbone19 = Backbone.noConflict(); // Backbone19 refers to the most recently loaded version, // and `window.Backbone` will be restored to the previously // loaded version
同时它还支持CommonJS规范
var Backbone; if (typeof exports !== 'undefined') { Backbone = exports; } else { Backbone = root.Backbone = {}; }
服务器支持
Backbone可以通过设置一个变量来表示HTTP服务器的支持:
Backbone.emulateHTTP = false; Backbone.emulateJSON = false;
Backbone.sync类似jquery ajax,其http参数基于jquery api。jquery ajax可能不能完全满足你的项目需求,那么,用同名方法就可以简单的重写它:
Backbone.sync = function(method, model, options) { };
对于模型的增、删、改、查,都提供了对应的方法,这里是默认的methodMap:
var methodMap = { 'create': 'POST', 'update': 'PUT', 'delete': 'DELETE', 'read': 'GET' };
事件
Backbone有一个内置的模块来处理事件,看一个例子:
on: function(events, callback, context) , aliased to bind off: function(events, callback, context) {, aliased to unbind trigger: function(events) {
每个方法都会返回this,推荐使用underscore去为对象添加事件:
// var object = {}; // _.extend(object, Backbone.Events); // object.on('expand', function(){ alert('expanded'); }); // object.trigger('expand');
这样你可以很容易将事件添加到项目中的其他对象中去,而不用担心覆盖现有对象。
模型
Backbones模型非常重要,它是一个构造函数,并通过设置各种不同的属性来管理模型。
你可以使用undersocre为backbone.events添加方法,模型的公用方法会被自动定义好。
需要注意的是,backbone.model是没有任何私有方法的构造函数。
set方法可以支持两种不同的类型(单个或多个属性):
if (_.isObject(key) || key == null) { attrs = key; options = value; } else { attrs = {}; attrs[key] = value; }
save方法也是类似的,下面,作者为了确保对象被设置了options,这可能比options = options || {}更好:
options || (options = {});
set方法会触发验证,并在验证失败后阻止进一步操作:
if (!this._validate(attrs, options)) return false;
接下来遍历每个属性,通过isEqual 方法验证,如果该属性被改变则记录下。一旦这个更改列表被建立,那么会调用change方法。
这个change事件会触发每个change方法,允许更改任何属性;举例说明,假如我有一个blogPost模型:
blogPost.on('change:title', function() { // 更新标题 }); blogPost.set('title', '测试一下');
注意,其他的方法也会触发change事件,如:unset,clear和fetch。实际上,他们都是通过set方法执行,并可以支持不同的options:
clear: function(options) { options = _.extend({}, options, {unset: true}); return this.set(_.clone(this.attributes), options); },
你可以使用fetch方法同步获取服务器端或持久层的数据,这个方法是可以被重写的。
sync方法用于将更改保存至服务器,isNew用于该模型的创建和更新,通过id属性来决定其状态,这样如果对持久层采用不同的方式就可以方便的覆盖。
须要注意的是,在backbone内部引用this.id不能映射到isNew的idAttribute。
总结一下本次学到的
- 通过重写sync方法可以操作任何持久层
- 事件驱动模型
- 模型change事件驱动UI变化
- 模型可知道何时创建或更新对象
- 使用模型、事件来组织项目架构是有好处的