一. Event
新建了一个对象,再与事件混合后,对象就可以用事件方法了。
例如:
1 var obj = {}; //js对象 2 _.extend(obj, Backbone.Events); //把Backbone.Events扩展到obj对象中。这时这个对象就拥有操作事件的方法了。_是underscore.js的对象,相当于jquery.js中的$ 3 4 obj.bind('data', function(data) { 5 console.log('Receive Data: ' + data); 6 }); 7 obj.trigger('data', 'I/'m an Backbone.event'); //打印Receive Data: I'm an Backbone.event 8 obj.unbind('data'); 9 obj.trigger('data', 'I/'m an Backbone.event');
另外,如果事件很多,可以给事件加上命名空间,例如"change:selection"。属性事件会先于正常事件触发。比如:
我们先监听了change事件,然后再监听了change:name属性事件,但change事件(改变name的值)在触发时,总是会先触发属性事件,然后再触发change事件。如果改变的不是name的值而是其他的值,这里只会触发change事件,而不会触发change:name属性事件。
二. Route(Controller)
var controller = Backbone.Controller.extend({
routes: {
"": "home",
"!/comments": "comments",
"!/mentions": "mentions",
"!/:uid": "profile",
"!/:uid/following": "following",
"!/:uid/followers": "followers",
"!/:uid/status/:id": "status",
"!/search/users/:query": "user_search",
"!/search/:query": "search"
},
initialize: function(){...} ,
home: function(){...} ,
comments: function() {...} ,
mentions: function() {...} ,
profile: function(a) {...} ,
status: function(a, b) {...} ,
following: function(a) {...} ,
followers: function(a) {...} ,
user_search: function(a) {...} ,
search: function(a) {...}
});
var custom = new controller();
Backbone.history.start();
... ...
三. Route(Controller)
view有两个作用,监听事件和显示数据
var view = Backbone.View.extend({
model: User, //这个View的模型
className: "components cross",
template: $("#user-info-template").html(),
initialize: function() { //new view({})就会调用这个初始化方法
_.bindAll(this, "render");
this.model.bind("change", this.render) //模型User绑定change事件
},
render: function() {
var a = this.model;
$(this.el).html(Mustache.to_html(this.template, a.toJSON())); //使用了Mustache模板库,来解析模板,把模型User中的数据,转换成json,显示在模板中
$(this.el).find(".days").html(function() { //再进行细微的改变
var b = a.get("created_at"); //取到模型User中的created_at的值
return b;
});
return this ;
}
});
在initialize中,一旦User类(模型)触发了change事件就会执行render方法,继而显示新的视图。
render方法中总是有个约定俗称的写法的。this.el是一个DOM对象,render的目的就是把内容填到this.el中。this.el会根据view提供的tagName, className, id属性创建,如果一个都没有,就会创建一个空的DIV。
更新完this.el后,我们还应该return this;这样才能继续执行下面的链式调用(如果有的话)。
我们也可以用$(view.el).remove()或者view.remove()很方便的清空DOM。
View层有一个委托事件的机制。
var view = Backbone.View.extend({
className: "likers-manager",
template: $("#likers-components-template").html(), //模板HTML
events: {
"click .btn-more": "loadMore"
},
initialize: function() { //new view({}),就会调用
_.bindAll(this, "render", "updateTitle", "loadOne", "loadAll", "loadMore"); //调用underscore的bingAll方法
},
render: function() { ... } ,
updateTitle: function() { ... } ,
loadOne: function(a) { ... } ,
loadAll: function() { ... } ,
loadMore: function(a) { ... }
});
在这里面有个events的键值对,格式为{"event selector": "callback"},其中click为事件,.btn-more是基于this.el为根的选择器,这样一旦约定好,当用户点击.btn-more的元素时,就会执行loadMore方法
四. Model
1. Model 用来创建数据,校验数据,存储数据到服务器端。Models还可以绑定事件。比如用户动作变化触发 model 的 change 事件,所有展示此model 数据的 views 都会接收到 这个 change 事件,进行重绘。
最简单的定义如下:
var Game = Backbone.Model.extend({});
稍微复杂一点:
var Game = Backbone.Model.extend({ initialize: function(){ }, defaults: { name: 'Default title', releaseDate: 2011, } });
initialize 相当于构造方法,初始化时调用(new时调用)
简单实用:
var portal = new Game({ name: "Portal 2", releaseDate: 2011}); var release = portal.get('releaseDate'); portal.set({ name: "Portal 2 by Valve"});
此时数据还都在内存中,需要执行save方法才会提交到服务器:
portal.save();
五. Collection
相当于Model的集合。需要注意的是,定义Collection的时候,一定要指定Model。 下面让我们为这个集合添加一个方法,如下:
var GamesCollection = Backbone.Collection.extend({ model : Game, old : function() { return this.filter(function(game) { return game.get('releaseDate') < 2009; }); } });
集合的使用方法如下:
var games = new GamesCollection games.get(0);
当然,也可以动态构成集合,如下:
var GamesCollection = Backbone.Collection.extend({
model : Game,
url: '/games'
});
var games = new GamesCollection
games.fetch();
这边的url告诉collection到哪去获取数据,fetch方法会发出一个异步请求到服务器,从而获取数据构成集合。(fetch实际上就是调用jquery的ajax方法)
模板解析是Underscore中提供的一个方法。且Underscore是Backbone必须依赖的库。
模板解析方法能允许我们在HTML结构中混合嵌入JS代码,就像在JSP页面中嵌入JAVA代码一样:
<ul> <% for(var i = 0; i < len; i++) { %> <li><%=data[i].title%></li> <% } %> </ul>
通过模板解析,我们不需要在动态生成HTML结构时,使用拼接字符串的方法,更重要的是,我们可以将视图中的HTML结构独立管理(例如:不同的状态可能会显示不同的HTML结构,我们可以定义多个单独的模板文件,按需加载和渲染即可)。在Backbone中,你可以使用on或off方法绑定和移除自定义事件。在任何地方,你都可以使用trigger方法触发这些绑定的事件,所有绑定过该事件的方法都会被执行,如:
var model = new Backbone.Model(); model.on('custom', function(p1, p2) { }); model.on('custom', function(p1, p2) { }); model.trigger('custom', 'value1', 'value2'); //将调用以上绑定的两个方法 model.off('custom'); model.trigger('custom'); // 触发custom事件,但不会执行任何函数,已经事件中的函数已经在上一步被移除
通过重载Backbone.sync方法来适配现有的数据接口