详解Backbone.js框架中的模型Model与其集合collection


Posted in Javascript onMay 05, 2016

什么是 Model
Backbone 的作者是这样定义 Model 的:

Model 是任何一个 web 应用的核心,它包含了交互的数据以及大部分的逻辑。例如:转化、验证、属性和访问权限等。
那么,我们首先来创建一个Model:

Person = Backbone.Model.extend({
  initialize: function(){
    alert("Welcome to Backbone!");
  }
});

var person = new Person;

上述代码中,我们定义了一个名为 Person 的 Model,实例化后,得到 person。任何时候当你实例化一个 Model,都会自动触发 initialize() 方法(这个原则同样适用于 collection, view)。当然,定义一个 Model 时,并非强制要求使用 initialize() 方法,但是随着你对 Backbone 的使用,你会发现它不可或缺。

设置 Model 属性
现在我们想在创建 Model 实例时传递一些参数用来设置 Model 的属性:

Person = Backbone.Model.extend({
  initialize: function(){
    alert("Welcome to Backbone!");
  }
});

//在实例化 Model 时直接设置
var person = new Person({ name: "StephenLee", age: 22 });

//我们也可以在 Model 实例化后,通过 set() 方法进行设置
var person = new Person();
person.set({ name: "StephenLee", age: 22});

获得 Model 属性
使用 Model 的 get() 方法,我们可以获得属性:

Person = Backbone.Model.extend({
  initialize: function(){
    alert("Welcome to Backbone!");
  }
});

var person = new Person({ name: "StephenLee", age: 22});

var age = person.get("age"); // 22
var name = person.get("name"); // "StephenLee"

设置 Model 默认属性
有时你希望 Model 实例化时本身就包含一些默认的属性值,这个可以通过定义 Model 的 defaults 属性来实现:

Person = Backbone.Model.extend({
  defaults: {
    name: "LebronJames",
    age: 30,
  },
  initialize: function(){
    alert("Welcome to Backbone!");
  }
});

var person = new Person({ name: "StephenLee"});

var age = person.get("age"); // 因为实例化时未指定 age 值,则为默认值 30
var name = person.get("name"); //实例化制定了 name 值,则为 "StephenLee"

使用 Model 属性
你可以在 Model 中自定义方法来使用 Model 内的属性。(所有自定义的方法默认为 public)

Person = Backbone.Model.extend({
  defaults: {
    name: "LebronJames",
    age: 30,
    hobby: "basketball"
  },
  initialize: function(){
    alert("Welcome to Backbone!");
  },
  like: function( hobbyName ){
    this.set({ hobby: hobbyName });
  },
});

var person = new Person({ name: "StephenLee", age: 22});

person.like("coding");// 设置 StephenLee's hobby 为 coding
var hobby = person.get("hobby"); // "coding"

监听 Model 属性的改变
根据 Backbone 的机制,我们可以给对 Model 的任意属性进行监听,接下来,我们尝试在 initialize() 方法中绑定 Model 一个的属性进行监听,以属性 name 为例:

Person = Backbone.Model.extend({
  defaults: {
    name: "LebronJames",
    age: 30,
  },
  initialize: function(){
    alert("Welcome to Backbone!");
    this.on("change:name", function(model){
      var name = model.get("name"); // 'KobeBryant'
      alert("Changed my name to " + name );
    });
  }
});

var person = new Person();

var age = person.set({name : "KobeBryant"});

通过上述代码,我们知道了如何对 Model 的某个属性进行监听。假设我们需要对 Model 所有的属性进行监听,则使用 'this.on("change", function(model){}); 。

服务器与 Model 的数据交互
前文中已提到 Model 包含了交互的数据,所以它的作用之一便是承载服务器端传来的数据,并与服务器端进行数据交互。现在我们假设服务器端有一个 mysql 的表 user,该表有三个字段 id, name, email 。服务器端采用 REST 风格与前端进行通信,使用 URL:/user 来进行交互。我们的 Model 定义为:

var UserModel = Backbone.Model.extend({
  urlRoot: '/user',
  defaults: {
    name: '',
    email: ''
  }
});

创建一个 Model
Backbone 中每个 Model 都拥有一个属性 id,它与服务器端数据一一对应。如果我们希望在服务器端的 mysql 表 user 中新增一条记录,我们只需要实例化一个 Model,然后调用 save() 方法即可。此时 Model 实例的属性 id 为空,即说明这个 Model 是新建的,因此 Backbone 将会向指定的 URL 发送一个 POST 请求。

var UserModel = Backbone.Model.extend({
  urlRoot: '/user',
  defaults: {
    name: '',
    email: ''
  }
});

var user = new Usermodel();
//注意,我们并没有在此定义 id 属性
var userDetails = {
  name: 'StephenLee',
  email: 'stephen.lee@mencoplatform.com'
};

//因为 model 没有 id 属性,所以此时使用 save() 方法,Backbone 会向服务器端发送一个 POST 请求,服务器端收到数据后,将其存储,并返回包含 id 的信息给 Model
user.save(userDetails, {
  success: function (user) {
    alert(user.toJSON());
  }
})

此时,在服务器端 mysql 的 user 表里多了一条 name 为 StephenLee,email 为 stephen.lee@mencoplatform.com 的记录。

取得一个 Model
刚刚我们已经创建了一个 Model,并将它存储到了服务器端的数据库中,假设创建 Model 时,服务器端返回的 id 属性值为 1,此时,我们通过 id 的值就可以将已存储的数据取回。当我们用 id 属性值初始化一个 Model 实例时,通过 fetch() 操作,Backbone 将会向指定的 URL 发送一个 GET 请求。

var user = new Usermodel({id: 1});//初始化时指定 id 的值

//利用 fetch() 方法将会向 user/1 请求数据,服务器端将会返回完整的 user 记录,包含 name,email 等信息
user.fetch({
  success: function (user) {
    alert(user.toJSON());
  }
})

更新一个 Model
如果我们需要对已经存储的 user 记录进行修改,利用已知的 id 值,同样使用 save() 方法,但因为此时 id 不为空,Backbone 将会向指定的 URL 发送一个 PUT 请求。

var user = new Usermodel({
  id: 1,
  name: 'StephenLee',
  email: 'stephen.lee@mencoplatform.com'
});//实例化时指定 id 值

//因为指定了 id 值,此时使用 save() 方法,Backbone 将会向 user/1 发送 PUT 请求,将会对数据库中 id 为1的记录的 email 修改
user.save({email: 'newemail@qq.com'}, {
  success: function (model) {
    alert(user.toJSON());
  }
});

删除一个 Model
如果我们需要删除数据库中的记录,利用已知的 id 值,使用 destroy() 方法即可。此时,Backbone 将会向指定的 URL 发送一个 DELETE 操作。

var user = new Usermodel({
  id: 1,
  name: 'StephenLee',
  email: 'stephen.lee@mencoplatform.com'
});//实例化时指定 id 值

//因为指定了 id 值,此时使用 destroy() 方法,Backbone 将会向 user/1 发送 DELETE 请求,服务器端接收请求后,将会在数据库中删除 id 为 1的数据
user.destroy({
  success: function () {
    alert('Destroyed');
  }
});

什么是 Collection
简而言之,Backbone 中的 Collection 就是 Model 的一个有序集合,比如,它可能会在以下情况中用到:

Model: Student, Collection: ClassStudents
Model: Todo Item, Collection: Todo List
Model: Animal, Collection: Zoo

Collection 一般只使用同一类型的 Model,但是 Model 可以属于不同类型的 Collection,比如:

Model: Student, Collection: Gym Class
Model: Student, Collection: Art Class
Model: Student, Collection: English Class

创建一个 Collection

//定义 Model Song
var Song = Backbone.Model.extend({
  defaults: {
    name: "Not specified",
    artist: "Not specified"
  },
  initialize: function(){
    console.log("Music is the answer");
  }
});

//定义 Collection Album
var Album = Backbone.Collection.extend({
  model: Song //指定 Collection 内的 Model 为 Song
});

var song1 = new Song({ name: "How Bizarre", artist: "OMC" });
var song2 = new Song({ name: "Sexual Healing", artist: "Marvin Gaye" });
var song3 = new Song({ name: "Talk It Over In Bed", artist: "OMC" });

var myAlbum = new Album([ song1, song2, song3]);
console.log( myAlbum.models ); // 输出为 [song1, song2, song3]
Javascript 相关文章推荐
JS小功能(操作Table--动态添加删除表格及数据)实现代码
Nov 28 Javascript
jquery插件hiAlert实现网页对话框美化
May 03 Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 Javascript
详解vue.js组件化开发实践
Dec 14 Javascript
vue引入jq插件的实例讲解
Sep 12 Javascript
深入理解Vue router的部分高级用法
Aug 15 Javascript
js中call()和apply()改变指针问题的讲解
Jan 17 Javascript
一文搞懂ES6中的Map和Set
May 20 Javascript
LayUI switch 开关监听 获取属性值、更改状态的方法
Sep 21 Javascript
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
Jul 21 Javascript
jQuery实现简单评论功能
Aug 19 jQuery
Vue router传递参数并解决刷新页面参数丢失问题
Dec 02 Vue.js
基于jQuery实现动态搜索显示功能
May 05 #Javascript
jQuery插件ajaxfileupload.js实现上传文件
Oct 23 #Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
May 05 #Javascript
js ajaxfileupload.js上传报错的解决方法
May 05 #Javascript
javascript执行环境及作用域详解
May 05 #Javascript
asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)
May 05 #Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
May 05 #Javascript
You might like
PHP安装攻略:常见问题解答(三)
2006/10/09 PHP
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
你可能不知道PHP get_meta_tags()函数
2014/05/12 PHP
php+mysqli数据库连接的两种方式
2015/01/28 PHP
php把数组值转换成键的方法
2015/07/13 PHP
PHP计算当前坐标3公里内4个角落的最大最小经纬度实例
2016/02/26 PHP
thinkPHP中验证码的简单实现方法
2016/12/05 PHP
CL vs ForZe BO5 第五场 2.13
2021/03/10 DOTA
用javascript getComputedStyle获取和设置style的原理
2008/10/10 Javascript
JS 文件大小判断的实现代码
2010/04/07 Javascript
JavaScript中诡异的delete操作符
2015/03/12 Javascript
深入学习jQuery Validate表单验证
2016/01/18 Javascript
基于javascript的Form表单验证
2016/12/29 Javascript
JavaScript运动框架 多物体任意值运动(三)
2017/05/17 Javascript
新手入门带你学习JavaScript引擎运行原理
2019/06/24 Javascript
微信小程序官方动态自定义底部tabBar的例子
2019/09/04 Javascript
JS实现秒杀倒计时特效
2020/01/02 Javascript
在Vue中使用CSS3实现内容无缝滚动的示例代码
2020/11/27 Vue.js
vue实现图片裁剪后上传
2020/12/16 Vue.js
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
[00:35]2016完美“圣”典风云人物:冷冷宣传片
2016/12/08 DOTA
python 文件和路径操作函数小结
2009/11/23 Python
在Python的Flask框架下使用sqlalchemy库的简单教程
2015/04/09 Python
基于wxPython的GUI实现输入对话框(2)
2019/02/27 Python
2019 Python最新面试题及答案16道题
2019/04/11 Python
Python序列类型的打包和解包实例
2019/12/21 Python
python实现logistic分类算法代码
2020/02/28 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
python lambda的使用详解
2021/02/26 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
HTML5 常见面试题之PC端和移动端区别介绍
2018/01/22 HTML / CSS
台湾森森购物网:U-mall
2017/10/16 全球购物
MATCHESFASHION.COM美国官网:英国奢侈品零售商
2018/10/29 全球购物
在职研究生自我鉴定
2013/10/16 职场文书
大型主题婚礼活动策划方案
2014/09/15 职场文书
毕业论文指导教师评语
2014/12/30 职场文书