详解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 相关文章推荐
Mozilla 表达式 __noSuchMethod__
Apr 05 Javascript
一段批量给页面上的控件赋值js
Jun 19 Javascript
两种方法实现文本框输入内容提示消失
Mar 17 Javascript
javascript同页面多次调用弹出层具体实例代码
Aug 16 Javascript
鼠标移入移出事件改变图片的分辨率的两种方法
Dec 17 Javascript
JavaScript数据结构和算法之图和图算法
Feb 11 Javascript
JavaScript控制网页平滑滚动到指定元素位置的方法
Apr 17 Javascript
用js实现放大镜的效果的简单实例
May 23 Javascript
Bootstrap BootstrapDialog使用详解
Feb 17 Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
Sep 19 Javascript
jquery分页插件pagination使用教程
Oct 23 jQuery
详解Vite的新体验
Feb 22 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截取视频指定帧为图片
2016/05/16 PHP
超级兔子让浮动层消失的前因后果
2007/03/09 Javascript
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
javascript自动改变文字大小和颜色的效果的小例子
2013/08/02 Javascript
js 实现浏览历史记录示例
2014/04/20 Javascript
jQuery中on()方法用法实例
2015/01/19 Javascript
jQuery解决input超多的表单提交
2015/08/10 Javascript
JS创建对象几种不同方法详解
2016/03/01 Javascript
JS模态窗口返回值兼容问题的完美解决方法
2016/05/28 Javascript
AngularJS HTML DOM详解及示例代码
2016/08/17 Javascript
浅谈在js传递参数中含加号(+)的处理方式
2016/10/11 Javascript
百度搜索框智能提示案例jsonp
2016/11/28 Javascript
Node.JS文件系统解析实例详解
2017/05/15 Javascript
VueJS 组件参数名命名与组件属性转化问题
2018/12/03 Javascript
node.js实现为PDF添加水印的示例代码
2018/12/05 Javascript
详解Vue用cmd创建项目
2019/02/12 Javascript
vue实现商品列表的添加删除实例讲解
2020/05/14 Javascript
vant时间控件使用方法详解
2020/12/24 Javascript
python递归函数绘制分形树的方法
2018/06/22 Python
Python用csv写入文件_消除空余行的方法
2018/07/06 Python
python实现随机梯度下降法
2020/03/24 Python
python导入pandas具体步骤方法
2019/06/23 Python
Django框架 querySet功能解析
2019/09/04 Python
python如何编写类似nmap的扫描工具
2020/11/06 Python
pycharm配置安装autopep8自动规范代码的实现
2021/03/02 Python
CSS3用@font-face实现自定义英文字体
2013/09/23 HTML / CSS
中国最大的潮流商品购物网站:YOHO!BUY有货
2017/01/07 全球购物
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
商务英语广告词大全
2014/03/18 职场文书
《永远的白衣战士》教学反思
2014/04/25 职场文书
2014年师德承诺书
2014/05/23 职场文书
公司周年庆活动方案
2014/08/25 职场文书
党员剖析材料范文
2014/09/30 职场文书
出纳工作检讨书范文
2014/12/27 职场文书
教师个人年度总结
2015/02/11 职场文书
广告业务员岗位职责
2015/02/13 职场文书