Backbone 学习笔记 01
简介
Backbone 是一个轻量级的库, 压缩后只有 16kb, 体积虽小, 但功能十分强大, 可以打造一个 模型(Model) - 视图(View) - 控制器(Controller) 即 MVC类结构的应用程序。
Model 是指数据, 比如一个人;
Collection 是指数据的集合, 比如一群人
View 是 Model 和 Collection 中数据的展示, 比如也数据渲染到页面
Router 是对路由的处理, 在单页面中通过 Router 来控制 View 的展示
依赖
Backbone.js 强制依赖 Underscore.js 这个库, 非强制依赖 jQuery, Zepto 等第三方库
<script src="jQuery.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
第一个 Backbone 应用页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>第一个 Backbone 页面应用</title>
</head>
<body>
<div id="divTip"></div>
<script src="http://apps.bdimg.com/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="http://apps.bdimg.com/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://apps.bdimg.com/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script>
$(function(){
// 定义模型类
window.Test = Backbone.Model.extend({
defaults : {
content : ""
}
})
// 创建集合类
window.TestList = Backbone.Collection.extend({
model : Test
})
// 向模型添加数据
var data = new TestList({
content : "Hello, Backbone!"
})
// 创建 View
window.TestView = Backbone.View.extend({
el : $("body"),
initialize : function(){
$("#divTip").html(data.models[0].get("content"))
}
})
// 实例化 View
window.app = new TestView
})
</script>
</body>
</html>
依赖库 Underscore.js
Underscore.js 是一个非常简洁的, 实用的库, 包含了 60 多个独立的函数, 这些函数可以在不拓展任何原生 JavaScript 对象的情况下, 为代码开发提供丰富的实用功能.
这里就不做过多详细的介绍了, 中文API
我写过一个关于 Underscore的博客, Underscore 源码阅读
事件管理
事件管理模块 Backbone.Events 在 Backbone 中十分重要, 其他模块 Model、Collection、View 所有事件模块都依赖它。
Backbone.Events 模块 API 结构
模块 Backbone.Events 的事件管理是通过 Backbone 提供的 Events API 来实现的。
1.0版本之前仅仅提供了几个基本的方法, 如 on
、off
、trigger
、once
分别执行对事件的绑定、解除绑定、执行事件、执行一次事件。
1.0版本之后又添加了几个实用方法, 如 listenTo
、listenToOnce
、stopListening
分别执行添加一个事件的侦听对象、添加一个仅执行一次的事件侦听对象和移除已添加的事件侦听对象。
基本事件方法
绑定 on 方法
使用 on
方法可以给一个对象自定义事件绑定触发该事件的执行函数, 当自定义事件触发时, 绑定的函数将运行
Obj.on(eventName, function, [context])
参数 Obj
表示对象本身; eventName
表示自定义事件名; function
表示当事件触发时, 被执行的函数; 可选参数 context
表示上下文环境
示例一 : 使用 on 方法监听默认事件
1.功能描述
构建一个名为 person
的模型类, 通过 defaults
设置对象的默认属性, 使用 on
方法 绑定对象默认属性的 change
事件
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : ""
}
});
var man = new person();
man.on("change", function(){
console.log("对象的属性值发生了改变")
})
man.set("name", "Lyf");
=> 输出 对象的属性值发生了改变
示例二 : 使用 on 方法监听属性事件
使用 on 方法监听对象的 change
事件时, 还可以监听到某个属性值的变化事件, 即属性事件。
Obj.on(eventName:attrName, function(model, value))
参数 eventName:attrName
表示对象的属性名称; 冒号(:) 是过滤符, 表示它是一个只针对某属性变化时触发的事件;
在触发的回调中, 参数 model
, 表示当前的数据模型对象, value
表示名为 attrName
属性修改后的值
1.功能描述
在示例一的基础上, 使用 on
方法绑定对象中是 sex
属性的 change
事件, 当 sex
属性值发生改变时, 触发该事件, 并在控制台输出最新值.
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "女"
}
});
var man = new person();
man.on("change", function(){
console.log("对象的属性值发生了改变")
})
man.on("change:sex", function(model, value){
console.log("您修改了性别属性值, 最新值是 : " + value)
})
man.set("sex", "男")
=> 您修改了性别属性值, 最新值是 : 男
=> 对象的属性值发生了改变
注意 : 当修改对象属性值的时候, 其事件的触发顺序是 : 先触发属性事件, 然后才触发默认的 change
事件
示例三 : 使用 on 方法获取属性修改前的值
使用 on 方法监听对象的 change
事件和 change
属性事件时, 还可以通过回调函数中的 model
对象获取属性修改前的值 :
model.previous("attrName")
model.previousAttributes()
previous()
方法是获取对象中某个属性的原有值, previousAttribute()
方法返回一个对象, 对象中包含上一个保存状态中的所有属性的原有值。这个方法只用于模型对象的 change
和 change
属性事件中获取上一个保存状态的属性值。
1.功能描述
分别绑定”分数”、”年龄”、属性的 change
事件。在事件中, 分别将属性重置前后的值进行对比, 并根据对比值在不同的浏览器的控制台中输出不同的内容.
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "女",
age : 32,
score : 120
}
});
var man = new person();
man.on("change:score", function(model, value){
var oldscore = model.previous("score")
if(value > oldscore){
console.log("您比上次进步了" + (value - oldscore) + "分")
} else if(value < oldscore){
console.log("您比上次落后了" + (oldscore - value) + "分")
} else {
console.log("您的成绩没有变化")
}
})
man.on("change:age", function(model, value){
var objAttr = model.previousAttributes();
var oldAge = objAttr.age;
if(value > oldAge){
console.log("您又年长了" + (value - oldAge) + "岁")
} else if(value < oldAge) {
console.log("您又年轻了" + (oldAge - value) + "岁")
} else {
console.log("您的年龄没有变化")
}
})
man.set({"age" : 35, "score" : 150})
=> 您又年长了3岁
=> 您比上次进步了30分
示例四 : 使用 on 方法绑定多个事件
在 Backbone 中, 除了使用 on
绑定单个事件, 还可以使用该方法同时绑定多个对象的事件.
绑定的方法有两种, 第一种语法如下 :
Obj.on(eventName1 eventName2, function)
使用空格隔开的参数 eventName1
和 eventName2
表示被绑定的多个事件的名称, function
表示所有被绑定的事件都要执行的自定义函数
1.功能描述
使用模型对象的 on
方法, 同时绑定 score、age 属性的 change
事件, 在该事件中, 分别获取重置时的原值和重置后的新值
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "女",
age : 32,
score : 120
}
});
var man = new person();
man.on("change:score change:age", function(model, value){
var oldage = model.previous("age");
var newage = model.get("age");
if(oldage != newage){
console.log("age 原值为 : " + oldage + ", 新值 : " + newage)
}
var oldscore = model.previous("score");
var newscore = model.get("score");
if(oldscore != newscore){
console.log("score 原值为 : " + oldscore + ", 新值 : " + newscore)
}
});
man.set("age", 36);
man.set("score", 150);
=> age 原值为 : 32, 新值 : 36
=> score 原值为 : 120, 新值 : 150
在使用 on
方法绑定事件中, 有两种格式可以绑定多个事件, 除了第一种使用空格外, 第二种方式为使用对象方式绑定多个事件 :
var ObjEvent = {
eventName1 : function1,
eventName2 : function2,
...
}
Obj.on(ObjEvent)
实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "女",
age : 32,
score : 120
}
});
var man = new person();
var objEvent = {
"change:score" : score_change,
"change:age" : age_change
}
man.on(objEvent);
function score_change(model, value){
var oldscore = model.previous("score");
var newscore = model.get("score");
if(oldscore != newscore){
console.log("score 原值为 : " + oldscore + ", 新值 : " + newscore)
}
}
function age_change(model, value){
var oldage = model.previous("age");
var newage = model.get("age");
if(oldage != newage){
console.log("age 原值为 : " + oldage + ", 新值 : " + newage)
}
}
man.set({"age" : 35, "score" : 150})
=> age 原值为 : 32, 新值 : 35
=> score 原值为 : 120, 新值 : 150
绑定一次 once 方法
once
方法绑定的事件只执行一次, 之后即使触发也不执行。调用格式如下 :
Obj.once(eventName, function, [context])
示例五 : 使用 once 方法绑定事件
1.功能描述
先使用模型对象的 once
方法绑定 change
事件, 在该事件中通过变量累计事件执行的次数, 并将该次数内容输出至浏览器的控制台中, 然后用 set
方法重置二次模型对象的属性.
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var initNum = 0;
man.once("change", function(){
initNum++;
console.log("事件触发的次数为" + initNum)
});
man.set("age", 26);
man.set("score", 150);
=> 事件触发的次数为1
触发事件 trigger 方法
前面介绍了 on
或者 once
方法绑定对象事件的过程, 这些事件都是对象本身自带的系统事件, 如 change
、change:age
等, 他们的触发需要满足相应的条件.
trigger
的功能是触发对象的某个事件 :
Obj.trigger(eventName)
其中 Obj
为对象本身, eventName
表示自定义的事件名, 需要手动触发的事件名。
trigger
可以手动触发对象的任何事件, 不仅是系统自带的事件, 还可以是自定义的事件。
示例六 : 使用 trigger 方法触发事件
1.功能描述
先使用 on
方法绑定模型对象的自定义事件 change_age_sex
和 age
属性的 change
事件,
然后分别调用 trigger
方法手动触发绑定的事件.
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
man.on("change_age_sex", function(){
console.log("您手动触发了一个自定义事件")
})
man.on("change:age", function(model, value){
if(value !== undefined)
console.log("您修改后的年龄为" + value)
else
console.log("您手动触发了一个年龄修改事件")
})
man.trigger("change_age_sex");
man.trigger("change:age");
man.set("age", 26);
=> 您手动触发了一个自定义事件
=> 您手动触发了一个年龄修改事件
=> 您修改后的年龄为26
移除事件 off 事件
与绑定事件的 on
方法相对的是移除事件的 off
方法, 该方法的功能是移除对象已绑定的某个、多个或全部的事件
Obj.off(eventName, function, [context])
其中参数 eventName
表示被移除的绑定事件名称, 该名称可以是单个也可以是多个, 如果是多个事件, 则用空格隔开。除移除对象绑定的事件之外, 还可以移除事件执行的函数, 即通过参数 function
来表示被移除的事件函数名。如果在调用 off
方法时不带任何参数, 表示移除对象的全部绑定事件。
示例七 : 使用 off 方法移除对象的某个或者多个事件
1.功能描述
先使用 on
方法绑定自定义事件, 又调用 off
方法移除已绑定的事件。
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var m = 0, n = 0;
var call_back_a = function(){
m++;
console.log("您执行a事件的次数为" + m);
}
var call_back_b = function(){
n++;
console.log("您执行b事件的次数为" + n);
}
man.on("event_a", call_back_a);
man.on("event_b", call_back_b);
man.off("event_a");
man.trigger("event_a event_b");
man.off("event_a event_b");
man.trigger("event_a event_b");
=> 您执行b事件的次数为1
示例八 : 使用 off 方法移除对象的某个函数
1.功能描述
使用 off
方法移除对象的某个函数
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var m = 0, n = 0;
var call_back_a = function(){
m++;
console.log("您执行a事件的次数为" + m);
}
var call_back_b = function(){
n++;
console.log("您执行b事件的次数为" + n);
}
man.on("event_a", call_back_a);
man.on("event_b", call_back_b);
man.off("event_a", call_back_a);
man.trigger("event_a event_b");
man.off("event_b", call_back_b);
man.trigger("event_a event_b");
=> 您执行b事件的次数为1
示例九 : 使用 off 方法移除对象全部绑定事件
在 Backbone 中, off
方法还可以通过不带参数的方式移除全部已绑定的事件。
1.功能描述
使用 off
移除全部已绑定的事件
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var m = 0, n = 0;
var call_back_a = function(){
m++;
console.log("您执行a事件的次数为" + m);
}
var call_back_b = function(){
n++;
console.log("您执行b事件的次数为" + n);
}
man.on("event_a", call_back_a);
man.on("event_b", call_back_b);
man.off();
man.trigger("event_a event_b");
新增事件方法
监听事件 listenTo 方法
相对于 on
方法而言, listenTo
方法的监听效果更为突出, 它是一个对象监听另一个对象的事件, 如果被监听的对象触发了被监听的事件, 执行相应的回调函数或代码块。
例如: view 对象要监听 model 对象的 change
事件, 如果 mode 对象触发了 change
事件, 则需要刷新当前 view 对象, 即执行下面代码 :
view.listenTo(model, "change", view.render)
也等价于
model.on("change", view.render, view)
其调用格式为
Obj1.listenTo(Obj2, eventName, function)
其中 Obj1
、Obj2
都是对象, eventName
为 Obj2
对象的触发事件名称, function
为当 Obj2
触发事件时调用的函数。
示例十 : 使用 listenTo 方法监听事件
1.功能描述
先调用 listenTo
方法绑定模型对象 age
属性的 change
事件。然后调用 set
方法重置对象的 age
属性, 在浏览器中输出变化时的原值与新值。
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var obj = _.extend({}, Backbone.Events);
obj.listenTo(man, "change:age", function(model, value){
var oldage = model.previous("age");
var newage = model.get("age");
if(oldage != newage){
console.log("age 原值" + oldage + ", 新值 : " + newage)
}
});
man.set("age", 37);
=> age 原值32, 新值 : 37
监听一次 listenToOnce 方法
除了使用 listenTo
方法可以进行对象级别监听外, 还可以使用 listenToOnce
方法进行对象级别的事件监听。
Obj1.listenToOnce(Obj2, EventName, function)
示例十一 : 使用 listenToOnce 方法监听事件
1.功能描述
先使用 listenToOnce
方法绑定对象 age
属性的 change
事件, 在事件中累计事件执行的次数, 并将次数输出。
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var obj = _.extend({}, Backbone.Events);
var initNum = 0;
obj.listenToOnce(man, "change:age", function(){
initNum++;
console.log("事件触发的次数为:" + initNum);
});
man.set("age", 37);
man.set("age", 38);
=> 事件触发的次数为:1
停止监听 stopListening 方法
与单个对象的 off
方法相同, 对象级别的事件监听也有停止方法即 stopListening
方法 :
Obj1.stopListening(Obj2, eventName, function)
示例十二 : 使用 stopListening 方法停止监听事件
1.功能描述
先使用 listenTo
方法绑定对象 age
属性的 change
事件, 然后分别调用 stopListening
方法停止事件的监听。
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
var obj = _.extend({}, Backbone.Events);
obj.listenTo(man, "change:name", function(model, value){
console.log("姓名修改后的值为:" + value);
});
obj.listenTo(man, "change:age", function(model, value){
console.log("年龄修改后的值为:" + value);
});
obj.listenTo(man, "change:score", function(model, value){
console.log("分数修改后的值为:" + value);
});
// 停止监听某一事件
obj.stopListening(man, "change:name");
man.set("name", "张三");
man.set("age", 25);
man.set("score", 150);
// 停止监听两个事件
obj.stopListening(man, "change:name change:age");
man.set("name", "李四");
man.set("age", 35);
man.set("score", 250);
// 停止所有事件
obj.stopListening();
man.set("name", "赵六");
man.set("age", 45);
man.set("score", 350);
=> 年龄修改后的值为:25
=> 分数修改后的值为:150
=> 分数修改后的值为:250
事件其他
特殊事件 all 的使用
all
是一个特殊的事件, 因为该事件在对象的任何事件被触发时, 它都会触发, 可以说是一个全局事件。它可以用 trigger
触发; 在触发该事件时, 还可以在回调的函数中通过 value
参数获取当前正在触发的事件名称。
Obj.on("all", function)
示例十三 : all 事件使用
1.功能描述
首先使用 on
方法绑定对象 name
、age
属性的 change
事件和特殊事件 all
, 然后在浏览器中输出
2.实现代码
var person = Backbone.Model.extend({
defaults : {
name : "",
sex : "男",
age : 32,
score : 120
}
});
var man = new person();
man.on("change:age", function(){
console.log("您触发了change:age事件");
});
var event_fun = function(){
console.log("您触发了change:name事件");
}
man.on("change:name", event_fun);
man.on("all", function(value){
console.log("您触发了all事件中" + value);
});
man.set("name", "Lyf");
man.set("age", 20);
=> 您触发了change:name事件
=> 您触发了all事件中change:name
=> 您触发了all事件中change
=> 您触发了change:age事件
=> 您触发了all事件中change:age
=> 您触发了all事件中change
事件与 Model、Collection 、View 的关系
示例十四 : 在 View 模块中定义事件
1.功能描述
在构建视图类时, 定义页面中的两个按钮的单击事件。单击”显示”按钮, 将页面中展示 <div>
元素的内容, 单击”隐藏”按钮时, 将隐藏 <div>
元素中的内容。
2.实现代码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>View 模块中的事件</title>
<style type="text/css">
body{
font-size: 12px;
}
</style>
</head>
<body>
<div id="view">
<input type="button" value="显示" id="btnShow">
<input type="button" value="隐藏" id="btnHide">
</div>
<div id="Info">
<span>This is a text .</span>
</div>
<script src="http://apps.bdimg.com/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="http://apps.bdimg.com/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://apps.bdimg.com/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script>
var infoView = Backbone.View.extend({
el : "#view",
events : {
"click #btnShow" : "ShowInfo",
"click #btnHide" : "HideInfo"
},
ShowInfo : function(){
$("#Info").show();
},
HideInfo : function(){
$("#Info").hide()
}
});
var view = new infoView();
</script>
</body>
</html>