什么是一个模型?
互联网上搜索到关于MVC的定义纷繁复杂且语焉不详以致于我们很难去定义模型应该干什么。然而backbone.js的作者很清楚模型在backbone.js中到底代表什么。
模型是任何JavaScript应用的核心部分,它拥有交互的数据以及包含数据的很大一部分逻辑:变换、验证、计算属性以及访问控制。
因此我们在这里创建一个模型。
Person = Backbone.Model.extend({
initialize: function(){
alert("Welcome to this world");
}
});
var person = new Person();
因此当你创建一个新的模型实例时initialize()方法被触发(模型,集合以及视图的运行方式都相同)。你并不一定要将这个方法包含到模型的声明中但是你会发现它在很多时候都很有用。
设置属性
现在我们来给一个模型的实例传递一些参数。
Person = Backbone.Model.extend({
initialize: function(){
alert("Welcome to this world");
}
});
var person = new Person({name: "Thomas", age: 67});
//或者我们可以在后面设置,结果完全是等价的
var person = new Person();
person.set({name: "Thomas", age: 67});
因此给构造器函数传递一个JavaScript对象完全等价于调用model.set()。既然模型的属性已经设置了,我们现在需要来提取它们。
获取属性
我们可以在任何时候使用model.get()方法来获取模型属性。
Person = Backbone.Model.extend({
initialize: function(){
alert("Welcome to this world");
}
});
var person = new Person({name: "Thomas", age: 67,child "Ryan"});
var age = person.get("age"); //67
var name = person.get("name"); //"Thomas"
var child = person.get("child"); //"Ryan"
设置模型默认属性
有时你会想要在模型中设置一些默认值。只要在模型声明中设置一个合适“defaults”默认名字就可以轻松实现。
Person = Backbone.Model.extend({
defaults:{
name: "Fetus",
age: 0,
child: ""
},
initialize: function(){
alert("Welcome to this world");
}
});
var person = new Person({name: "Thomas", age: 67, child: "Ryan"});
var age = person.get("age"); //67
var name = person.get("name"); //"Thomas"
var child = person.get("child"); //"Ryan"
操作模型属性
模型可以包含任意多的自定义方法来让你操作属性。默认的所有的方法都是公共方法。
Person = Backbone.Model.extend({
defaults:{
name: "Fetus",
age: 0,
child: ''
},
initialize: function(){
alert("Welcome to this world");
},
adopt: function(newChildsName){
this.set({child: newChildsName });
}
});
var person = new Person({name: "Thomas", age: 67, child: "Ryan"});
person.adopt("John Resig"); // .......为什么要黑人家
var child = person.get("child"); // "Jogn Resig"
所以我们现在可以实现一些方法对模型的任何属性进行获取/设置并进行其他的计算了。
监听模型的变化
现在我们要开始讲述使用诸如backbone这样的库的一个好处了。一个模型的所有属性都可以绑定监听器来探测它们的值的变化。在initialize函数中我们可以绑定一个函数,当模型中的任何属性值发生改变时它就被调用。在这里的情形中如果我们的“person”的name发生变化,我们就alert新的name。
Person = Backbone.Model.extend({
defaults:{
name: "Fetus",
age: 0,
child: ""
},
initialize: function(){
alert("Welcome to this world");
this.on("change:name", function(model){
var name = model.get(name); //'Stewie Griffin'
alert("Changed my name to " + name);
});
}
});
var person = new Person({name: "Thomas", age: 67});
person.set({name: 'Stewie Griffin'});//这将触发change事件以及alert()
因此我们现在可以绑定change监听器到任何属性上或者我们可以简单的使用”this.on(”change”,function(model){})”来监听模型上的所有属性变化。
与服务器交互
模型被用来呈现来自服务器的数据以及将你在模型上的操作转化为RESTful操作。
一个模型的id属性指明了怎样在数据库汇总找到它,并且通常映射到surrogate key。
在这里我们假设我们有一张叫做Users的mysql表格,它有id,name,email三列。
服务器已经实现了一个RESTful URL /user,我们可以和它进行交互。
我们的模型定义如下所示:
var UserModel = Backbone.Model.extend({
urlRoot: '/user',
defaults: {
name: '',
email: ''
}
});
创建一个新模型
如果我们想要在服务器上创建一个新的用户我们需要实例化一个UserModel然后调用save方法。如果模型的id属性是null,Backbone.js将会发送一个POST请求到服务器的urlRoot。
var UserModel = Backbone.Model.extend({
urlRoot: '/user',
defaults: {
name: '',
email: ''
}
});
var user = new Usermodel();
//注意到我们没有设置一个'id'属性
var userDetails = {
name: 'Thomas',
email: 'thomasalwyndavis@gmail.com'
};
//因为我们没有设置一个'id'属性,服务器将会调用POST /user 连同一个{name: 'Thomas',email: 'thomasalwydavis@gmail.com'}
//服务器应该保存数据并且返回一个包含新的'id'的相应
user.save(userDetails,{
success: function(user){
alert(user.toJSON());
}
});
我们的表格现在应该有这些值:
1,'Thomas','thomasalwydavis@gmail.com'
获取一个模型
既然我们已经存储了一个新的user模型,我们可以从服务器获取它。我们知道上面例子中的id是1。
如果我们实例化一个id是1的模型,Backbone.js将就自动加上’/id’从urlRoot发送一个get请求。(符合RESTful的传统)
//在这里我们设置了模型的id
var user = new UserModel({id: 1});
//下面的获取将会执行GET /user/1
//服务器将会从数据库中返回id,name以及email
user.fetch({
success: function(user){
alert(user.toJSON());
}
});
更新一个模型
既然我们的模型已经存在于服务器上,我们可以使用一个PUT请求来执行一个更新操作。我们将使用save API,它很智能,如果已经有一个id存在它将发送一个PUT请求而不是一个POST请求。
//这里我们设置这个模型的'id'
var user = new Usermodel({
id: 1,
name: 'Thomas',
email: 'thomasalwydavis@gmail.com'
});
//现在我们改变name并更新服务器
//因为已经有一个'id'存在了,Backbone.js将会连同
//‘{name: 'Davis',email: 'thomasalwydavis@gmail.com'}’一起触发PUT /user/1
user.save({name: 'Davis'},{
success: function(model){
alert(user.toJSON());
}
});
删除一个模型
当一个模型拥有了一个id时我们知道它已经存在于服务器上了,因此如果我们想要从吴福气上将它移除我们可以调用destory.destory将处罚DELETE /user/id(符合RESTful的传统)。
//在这里我们设置一个模型的'id'
var user = new Usermodel({
id: 1,
name: 'Thomas',
email: 'thomasalwyndavis@gmail.com'
});
//因为已经存在'id',Backbone.js将会触发
//DELETE /user/1
user.destory({
success: function(){
alert('Destoryed');
}
});
提示和技巧
获取当前所有属性
var person = new Person({name: 'Thomas', age: 67 });
var attribute = person.toJSON(); //{name: "Thomas", age: 67}
//这样简单的返回了一个当前属性的副本
var attributes =person.attributes;
//上面这行代码给你了一个直接饮用你应该很小心的使用它。最佳实践
//建议你使用.set()来编辑模型的属性并使用backbone的监听器
在设置并存储数据之前先进行验证
Person = Backbone.Model.extend({
//如果你从validate函数返回一个字符串
//Backbone将会抛出一个错误
validate: function(attributes){
if(attributes.age < 0 && attributes.name != "Dr Manhatten"){
return "You can't be negative years old";
}
}.
initialize: function(){
alert("Welcome to this world");
this.bind("error",function(model.error){
//我们会接收到一个错误,打印它,提示它,或者忽略它
alert(error)
});
}
});
var person = new Person;
person.set({name "Mary Poppins", age: -1});
//将会出大一个alert输出错误
var person = new Person;
person.set({name: "Dr Manhatten", age: -1});
//仁慈的上帝保佑我们的灵魂