详解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 相关文章推荐
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
Jul 29 Javascript
JavaScript变量声明详解
Nov 27 Javascript
介绍JavaScript中Math.abs()方法的使用
Jun 14 Javascript
jquery+php实现滚动的数字特效
Nov 29 Javascript
js判断当前页面在移动设备还是在PC端中打开
Jan 06 Javascript
基于JavaScript代码实现自动生成表格
Jun 15 Javascript
Angular2环境搭建具体操作步骤(推荐)
Aug 04 Javascript
浅谈Angular2 ng-content 指令在组件中嵌入内容
Aug 18 Javascript
JS实现520 表白简单代码
May 21 Javascript
javascript防抖函数debounce详解
Jun 11 Javascript
微信小程序嵌入腾讯视频源过程详解
Aug 08 Javascript
解决vscode进行vue格式化,会自动补分号和双引号的问题
Oct 26 Javascript
基于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/11/25 PHP
使用PHPCMS搭建wap手机网站
2015/09/20 PHP
php框架CodeIgniter主从数据库配置方法分析
2018/05/25 PHP
php实现微信公众号企业转账功能
2018/10/01 PHP
Prototype Object对象 学习
2009/07/12 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
2012/10/11 Javascript
jquery实现带单选按钮的表格行选中时高亮显示
2013/08/01 Javascript
使用jQuery判断IE浏览器版本的代码
2014/06/14 Javascript
jQuery实现的导航条切换可显示隐藏
2014/10/22 Javascript
javascript正则表达式之search()用法实例
2015/01/19 Javascript
nodejs实现获取某宝商品分类
2015/05/28 NodeJs
js实现适用于素材网站的黑色多级菜单导航条效果
2015/08/24 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
AngularJS解决ng界面长表达式(ui-set)的方法分析
2016/11/07 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
Angular实现的自定义模糊查询、排序及三角箭头标注功能示例
2017/12/28 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
2019/06/07 Javascript
简单了解JavaScript中的执行上下文和堆栈
2019/06/24 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
[01:15:44]首部DOTA2纪录片今日23时全网上映
2014/03/19 DOTA
[04:16]完美世界DOTA2联赛PWL S2 集锦第一期
2020/11/23 DOTA
python简单实现最大似然估计&scipy库的使用详解
2020/04/15 Python
pytorch实现查看当前学习率
2020/06/24 Python
机关门卫的岗位职责
2014/04/29 职场文书
超市优秀员工事迹材料
2014/05/01 职场文书
个人委托书如何写
2014/09/25 职场文书
个人债务授权委托书范本
2014/10/05 职场文书
2014年人事专员工作总结
2014/11/19 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
2015年员工试用期工作总结
2015/05/28 职场文书
公文写作:教你写“建议书”
2019/05/07 职场文书
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs
Python 中的Sympy详细使用
2021/08/07 Python
Redis之RedisTemplate配置方式(序列和反序列化)
2022/03/13 Redis
简单聊一聊SQL注入及防止SQL注入
2022/03/23 MySQL