Backbone 学习笔记 02
数据模型
Model 在 Backbone 中为数据模型, 是一个最基础、最根本的数据基类, 用于原始数据、底层方法的封装和定义。
创建数据模型
在 Backbone 中, 创建数据模型的方法十分简单, 只要通过 Model.extend()
就可以定义一个数据模型。它在定义过程中, 还可以初始化数据、定义构造方法, 当一个数据模型创建成功后, 可以通过实例化的方法, 产生一个个数据对象。这些数据都继承了数据模型中的初始化数据, 并能够方便的调用。
创建一个简单的模型对象
当使用 Model.extend()
方法构建数据模型之后, 就可以通过实例化方式创建一个模型的对象, 模型对象将自动继承模型中定义的属性和方法。
示例一 : 创建一个简单的模型对象
var student = Backbone.Model.extend({
initialize : function(){
initNum++;
console.log("您构建了" + initNum + "个对象");
}
});
var initNum = 0;
var student1 = new student();
var student2 = new student();
=> 您构建了1个对象
=> 您构建了2个对象
对象赋值的方法
对于一个数据模型, 赋值的方法在定义时通过 defaults
属性设置数据模型的默认值, 对于一个已经实例化的模型对象, 赋值的方法为 set
方法, 重置模型的默认值。set
方法有两种形式 :
第一种是单个设置 :
Obj.set(attrName, attrValue)
第二种为批量设置属性值
Obj.set({attrName1 : attrValue1, attrName2 : attrValue2, ....})
无论使用 set
方法的何种形式赋值, 当完成对象赋值操作之后, 就可以通过调用对象的 get
或 escape
方法获取已设置的对象属性值。调用格式如下 :
Obj.get(attrName)
Obj.escape(attrName)
示例二 : 对象模型赋值的方法
var student = Backbone.Model.extend({
initialize : function(){
// 执行构造代码
},
defaults : {
Code : "",
Name : "",
Score : ""
}
});
var student1 = new student();
student1.set({
Code : "10001",
Name : "张三",
Score : "120",
Class : "一年级"
});
console.log(student1.get("Name") + "在" + student1.get("Class") + "读小学");
=> 张三在一年级读小学
自定义模型中的方法
在构建对象模型时, 不仅可以设置模型对象的默认属性, 而且还可以自定义模型对象的方法, 在方法中 this
表示模型本身。
示例三 : 自定义方法
var student = Backbone.Model.extend({
initialize : function(){
// 执行构造代码
},
defaults : {
Code : "",
Name : "",
Score : ""
},
printLog : function(){
console.log(this.get("Name") + "在" + this.get("Class") + "读小学");
}
});
var student1 = new student();
student1.set({
Code : "10001",
Name : "张三",
Score : "120",
Class : "一年级"
});
student1.printLog();
=> 张三在一年级读小学
监听对象属性值变化
在构建数据模型时, 使用 on
方法去绑定对象的属性事件, 监听属性值的变化, 通常放在数据模型构造函数 initialize
。
示例四 : 监听 Name 属性值的变化
var student = Backbone.Model.extend({
initialize : function(){
this.on("change:Name", function(){
var oldName = this.previous("Name");
var newname = this.get("Name");
if(oldName != newname){
console.log("Name 原值 : " + oldName + ", 新值 : " + newname);
}
})
},
defaults : {
Code : "",
Name : "name",
Score : ""
}
});
var student1 = new student();
student1.set({
Code : "10001",
Name : "张三",
Score : "120",
Class : "一年级"
});
=> Name 原值 : name, 新值 : 张三
模型对象操作
创建一个数据模型类后, 接下来的任务就是针对模型对象实例化对象, 并对实例化后的对象进行一系列的数据操作。
读取数据
如果要读取一个模型对象中的数据, 通常调用对象的 get
和 escape
方法, 前者是直接返回对象的数据, 后者是返回经过对对象中某些特殊字符进行编码的数据。
示例五 : 调用 get 方法获取对象指定的属性值
var student = Backbone.Model.extend({
defaults : {
Code : "",
Name : "",
Score : ""
}
});
var student1 = new student({
Name : "张三"
});
console.log(student1.get("Name"))
=> 张三
修改数据
完成一个数据模型的构建之后, 就可以通过实例化的对象修改模型类中的默认属性值。常用的有两种方法 : 一种是在实例化的时候修改默认属性; 一种是调用对象的 set
方法针对一个或者多个属性进行重置。
示例六 : 调用 set 方法批量修改重置默认值
var student = Backbone.Model.extend({
defaults : {
Code : "",
Name : "",
Score : ""
}
});
var student1 = new student({
Code : "10001",
Name : "张三",
Score : 150
});
var student2 = new student();
student2.set({
Code : "10002",
Name : "李四",
Score : 150
});
开启数据验证
Backbone 提供了一套完整的数据验证机制, 用于确保写入数据模型的正确性。
要实现数据的验证, 需要以下3个步骤 :
1.添加 validate
方法, 在该方法中提供数据的校验, 即数据在什么情况下, 认为它是不正确的, 如果不正确返回提示信息。
2.绑定对象的 invalid
方法, 数据验证失败后会触发该事件, 在该事件中, 通过返回的参数可以接收 validate
方法中传递的提示信息。
3.使用 set
方法添加/修改属性时, 必须将 validate
属性值设置为 true
, 用于通知 Backbone 框架此次数据操作时需要验证的。
示例七 : 开启数据验证
var student = Backbone.Model.extend({
initialize : function(){
this.on("invalid", function(model, error){
console.log(error)
});
},
validate : function(attrs){
if(!_.isString(attrs.Name)) return "姓名必须是字符串"
if(!_.isNumber(attrs.Score)) return "分数必须是数字"
},
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : 120,
Score : "李四"
}, {"validate" : true});
console.log(student1.toJSON());
=> 姓名必须是字符串
=> Object {Code: "10001", Name: "张三", Score: 120}
关闭数据验证
在 Backbone 中, 调用 set
方法, 不将 validate
属性值设置为 true
, 本次 set
将不会进行数据验证。此外, 还可以将 silent
属性设置为 true
, 表示静默式修改数据, 即再修改数据的时候, 不触发任何事件。
示例八 : 关闭数据验证
var student = Backbone.Model.extend({
initialize : function(){
this.on("invalid", function(model, error){
console.log(error)
});
},
validate : function(attrs){
if(!_.isString(attrs.Name)) return "姓名必须是字符串"
if(!_.isNumber(attrs.Score)) return "分数必须是数字"
},
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : 120,
Score : "李四"
}, {"silent" : true});
console.log(student1.toJSON());
=> Object {Code: "10001", Name: "120", Score: "李四"}
更新数据回滚
在 Backbone 中调用 set
方法, 可以将 silent
属性设置为 true
, 为了保证数据安全, 可以调用对象的 previous
方法进行数据回滚。
示例九 : 更新数据回滚
var student = Backbone.Model.extend({
initialize : function(){
this.on("invalid", function(model, error){
console.log(error)
});
},
validate : function(attrs){
if(!_.isString(attrs.Name)) return "姓名必须是字符串"
if(!_.isNumber(attrs.Score)) return "分数必须是数字"
},
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : 120,
Score : "李四"
}, {"silent" : true});
console.log(student1.toJSON());
if(!_.isString(student1.get("Name")) || !_.isNumber(student1.get("Score"))){
student1.set({
"Name" : student1.previous("Name"),
"Score" : student1.previous("Score")
})
}
console.log(student1.toJSON());
=> Object {Code: "10002", Name: 120, Score: "李四"}
=> Object {Code: "10002", Name: "张三", Score: 120}
删除数据
在 Backbone 中, 可以调用对象的 unset
和 clear
方法删除模型对象的数据, 前者是删除指定属性名称的数据, 调用格式 :
Obj.unset(attrName)
后者为清除对象中的全部数据, 该方法没有参数, 调用格式如下 :
Obj.clear()
示例十 : 调用 unset 方法删除指定属性的数据
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : "张三",
Score : 120
});
// 删除 Name 属性
student1.unset("Name");
console.log(student1.get("Name"));
console.log(student1.toJSON());
student1.set("Name", student1.previous("Name"));
console.log(student1.toJSON());
// 清除全部数据
student1.clear();
console.log(student1.toJSON());
=> undefined
=> Object {Code: "10002", Score: 120}
=> Object {Code: "10002", Score: 120, Name: "张三"}
=> Object {}
对象属性操作
attributes 对象
在 Backbone 中, 实例化的模型对象所有属性都保存在一个名为 attributes
的对象中, 对象的 set
和 get
方法都是围绕这个对象中存取的。
示例十一 : 调用 attributes 对象获取全部的属性值
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : "李四",
Score : 120
});
// 直接输出 attributes
console.log(student1.attributes);
// 遍历后输出 attributes
var attrs = student1.attributes;
for(var i in attrs){
console.log(i + ":" + attrs[i]);
}
=> Object {Code: "10002", Name: "李四", Score: 120}
=> Code:10002
=> Name:李四
=> Score:120
previous 和 previousAttributes 方法
这两个方法都用来返回对象在修改前上一个状态的属性值,第一种调用格式如下 :
obj.previous(attrName)
第二种方法返回一个对象, 包含上一个状态的全部数据, 该方法没有参数, 调用方法如下 :
obj.previousAttribute()
这两种方法都必须用在 set
方法重置数据后使用, 如果没有使用 set
方法, 就直接调用 previous
和 previousAttribute
, 将会导致异常。
示例十二 : 调用 previousAttribute 方法返回数据
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : "李四",
Score : 120
});
console.log(student1.toJSON());
console.log(student1.previousAttributes());
=> Object {Code: "10002", Name: "李四", Score: 120}
=> Object {Code: "10001", Name: "张三", Score: 120}
同步数据到服务器
在 Backbone 中, 客户端的静态页面与服务器之间的数据, 可以通过 save
、fetch
、destroy
方法分别实现在服务器中保存、获取、删除数据的操作, 通过这些方法可以实现客户端与服务端之间的无缝连接, 完成客户端数据与服务端的同步。
save 方法
在 Backbone 中, 对象 save
方法的功能是在服务器中保存客户端发送的数据, 在数据发送过程中, 还能通过模型内部的 isNew
方法检测数据是否新建还是更新, 如果是新建, 通过 POST
方法发送, 否则通过 PUT
方式发送。服务器根据数据发送的方式进行数据添加或更新, 并向客户端返回操作结果, 客户端根据结果进行下一步操作。
示例十三 : 使用 save 方法发送数据
当一个实例化后的模型对象在模型中设置服务器请求地址 url 属性后, 可以直接调用对象的 save
方法, 向服务器发送数据。
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
url : "/Ch4/api/save.php",
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : "李四",
Score : 120
});
student1.save();
示例十四 : 使用 save 接收返回值
使用对象的 save
方法发送数据至服务器, 服务器将接收发送数据写入数据库, 实现保存或修改的功能。操作完成后, 将向客户端发送一个成功或者失败的标志, 客户端根据这一返回值进行下一步操作。
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
url : "/Ch4/api/save.php",
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.set({
Code : "10002",
Name : "李四",
Score : 120
});
student1.save(null, {
success : function(model, response){
console.log(response.code);
}
});
示例十五 : 使用 save 方法时设置 wait 属性
在调用 save
方法向服务器保存数据时, 不仅可以在配置对象中添加 success
或者 error
函数, 还可以将 wait
属性设置为 true
。在配置对象中, 将 wait
属性设置为 true
时, 将会调用 validate
方法, 对发送的数据进行验证, 如果没有通过验证, 将不会向服务器发送数据, 对象进行回滚, 返回上一状态。此外, 向服务器发送数据时, 如果请求失败也将导致数据的回滚。
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
url : "save2.php", // 这里不存在这个文件
defaults : {
Code : "10001",
Name : "张三",
Score : 120
}
});
var student1 = new student();
student1.save({
Code : "10002",
Name : "李四",
Score : 120
}, {
success : function(model, response){
console.log(response.code);
},
wait : true
});
console.log(student1.toJSON());
fetch 方法
与 save
方法不同, fetch 方法的功能是从服务器获取数据, 常用于数据模型初始化或数据恢复, 该方法采用 get 方式请求服务器中的数据, 当请求成功后, 将调用 set
方法重置模型的 this.attributes
对象。同时, 如果重置成功, 调用 success
函数, 否则直接返回。
示例十六 : 使用 fetch 方法获取服务器数据
var student = Backbone.Model.extend({
initialize : function(){
// 构造函数
},
url : "fetch.php"
});
var student1 = new student();
student1.fetch({
success : function(model, response){
console.log(student1.toJSON())
},
error : function(err){
console.log("error")
}
})
destroy 方法
在 Backbone 中, 当调用对象的 destroy
方法时, 将以 DELETE 请求方式向服务器发送对象的 ID 数据, 服务器接收该数据后删除对应的数据记录, 并向客户端发送删除成功的标志。
由于是删除对象的数据, 因此在调用 destroy
方法时, 必须发送 ID 号属性, 如果不存在该属性, 通过 idAttribute
属性进行设置, 否则不会发送数据请求操作。
此外, 在调用 destroy
方法时, 也可以配置 success
、error
函数、或将 wait
属性设置为 true
, 当请求服务器删除数据成功并接收返回值后, 不仅触发绑定的 destroy
事件, 而且还调用 success
函数; 当请求服务器失败时, 将 wait
属性设为 true
, 则不会触发绑定的 destroy
事件, 否则会触发 destroy
事件并且执行 error
函数。
示例十七 : 使用 destroy 方法从服务器删除数据
var student = Backbone.Model.extend({
initialize : function(){
this.on("destroy", function(){
console.log("正在调用 destroy 方法");
})
},
url : "destroy.php",
idAttribute : "Code"
});
var student1 = new student({
Code : "10002"
});
student1.destroy({
success : function(model, response){
if(response.code == 0){
console.log("Code为" + model.get("Code") + "的数据已删除")
}
},
error : function(error){
console.log(error)
},
wait : true
})