详解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 相关文章推荐
jQuery Tools Dateinput使用介绍
Jul 14 Javascript
jQuery之排序组件的深入解析
Jun 19 Javascript
Json序列化和反序列化方法解析
Dec 19 Javascript
使用时间戳解决ie缓存的问题
Aug 20 Javascript
jQuery手动点击实现图片轮播特效
Apr 20 Javascript
javascript与jquery中的this关键字用法实例分析
Dec 24 Javascript
jQuery手风琴的简单制作
May 12 jQuery
利用JQUERY实现多个AJAX请求等待的实例
Dec 14 jQuery
vue router动态路由设置参数可选问题
Aug 21 Javascript
layui form表单提交之后重新加载数据表格的方法
Sep 11 Javascript
使用javascript解析二维码的三种方式
Nov 11 Javascript
JS前端可视化canvas动画原理及其推导实现
Aug 05 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 && 逻辑与运算符使用说明
2010/03/04 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
2016/09/01 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
PDO::query讲解
2019/01/29 PHP
JavaScript 异步调用框架 (Part 4 - 链式调用)
2009/08/04 Javascript
javascript的原生方法获取数组中的最大(最小)值
2012/12/19 Javascript
node.js中的fs.utimes方法使用说明
2014/12/15 Javascript
基于jquery实现图片放大功能
2016/05/07 Javascript
bootstrapValidator表单验证插件学习
2016/12/30 Javascript
基于MVC方式实现三级联动(JavaScript)
2017/01/23 Javascript
jQuery实现列表的增加和删除功能
2018/06/14 jQuery
在vue中多次调用同一个定义全局变量的实例
2018/09/25 Javascript
微信小程序的线程架构【推荐】
2019/05/14 Javascript
了解JavaScript中的选择器
2019/05/24 Javascript
Js实现复选框的全选、全不选反选功能代码实例
2020/02/28 Javascript
微信小程序国际化探索实现(附源码地址)
2020/05/20 Javascript
详解Python读取配置文件模块ConfigParser
2017/05/11 Python
Python之Scrapy爬虫框架安装及简单使用详解
2017/12/22 Python
pyqt5让图片自适应QLabel大小上以及移除已显示的图片方法
2019/06/21 Python
如何通过Python3和ssl实现加密通信功能
2020/05/09 Python
浅谈Python爬虫原理与数据抓取
2020/07/21 Python
python装饰器三种装饰模式的简单分析
2020/09/04 Python
python3从网络摄像机解析mjpeg http流的示例
2020/11/13 Python
Python爬虫之App爬虫视频下载的实现
2020/12/08 Python
使用纯 CSS 创作一个脉动 loader效果的源码
2018/09/28 HTML / CSS
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
彪马香港官方网上商店:PUMA香港
2020/12/06 全球购物
加拿大著名的奢侈品购物网站:SSENSE(支持中文)
2020/06/25 全球购物
办公自动化毕业生求职信
2014/03/09 职场文书
电视购物广告词
2014/03/19 职场文书
公司员工活动策划方案
2014/08/20 职场文书
公司领导班子四风对照检查材料
2014/09/27 职场文书
事业单位工作人员年度考核个人总结
2015/02/12 职场文书
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android