详解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.Treeview添加右键菜单的实现代码
Oct 22 Javascript
常用js字符串判断方法整理
Oct 18 Javascript
JQuery获取或设置ckeditor的数据(示例代码)
Nov 15 Javascript
JS实现的生成随机数的4个函数分享
Feb 11 Javascript
jQuery使用元素属性attr赋值详解
Feb 27 Javascript
BootStrap无限级分类(无限极分类封装版)
Aug 26 Javascript
浅析JS中对函数function的理解(基础篇)
Oct 14 Javascript
JavaScript表单验证的两种实现方法
Feb 11 Javascript
jquery radio 动态控制选中失效问题的解决方法
Feb 28 jQuery
ios设备中angularjs无法改变页面title的解决方法
Sep 13 Javascript
JS实现打砖块游戏
Feb 14 Javascript
详解vue-flickity的fullScreen功能实现
Apr 07 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数据采集的详解
2013/06/02 PHP
学习php设计模式 php实现建造者模式
2015/12/07 PHP
PHP操作Redis数据库常用方法示例
2018/08/25 PHP
Visual Studio中的jQuery智能提示设置方法
2010/03/27 Javascript
jquery实现图片等比例缩放以及max-width在ie中不兼容解决
2013/03/21 Javascript
JavaScript Math.ceil 方法(对数值向上取整)
2015/01/09 Javascript
jQuery ready()和onload的加载耗时分析
2016/09/08 Javascript
利用VUE框架,实现列表分页功能示例代码
2017/01/12 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
ExtJs异步无法向外传值和赋值的完美解决办法
2017/06/14 Javascript
原生JS+CSS实现炫酷重力模拟弹跳系统的登录页面
2017/11/01 Javascript
vue2中的keep-alive使用总结及注意事项
2017/12/21 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
2020/04/12 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
2018/05/09 Javascript
Angularjs中的$apply及优化使用详解
2018/07/02 Javascript
JS数组的常用10种方法详解
2020/05/08 Javascript
原生JS封装拖动验证滑块的实现代码示例
2020/06/01 Javascript
Python实现周期性抓取网页内容的方法
2015/11/04 Python
Python基于pygame实现的弹力球效果(附源码)
2015/11/11 Python
详解Python import方法引入模块的实例
2017/08/02 Python
Python SQL查询并生成json文件操作示例
2018/08/17 Python
Django-Model数据库操作(增删改查、连表结构)详解
2019/07/17 Python
wxPython实现整点报时
2019/11/18 Python
python 实现将小图片放到另一个较大的白色或黑色背景图片中
2019/12/12 Python
django 读取图片到页面实例
2020/03/27 Python
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
Tuckernuck官网:经典的美国品质服装、鞋子和配饰
2021/01/11 全球购物
心得体会开头
2014/01/01 职场文书
公司拓展活动方案
2014/02/13 职场文书
项目负责人任命书
2014/06/04 职场文书
博士生导师推荐信
2014/07/08 职场文书
新人入职感言
2015/07/31 职场文书
初中美术教学反思
2016/02/17 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
python中filter,map,reduce的作用
2022/06/10 Python
css3手动实现pc端横向滚动
2022/06/21 HTML / CSS