本文转自:http://weakfi.iteye.com/blog/1391990

什么是backbone

backbone不是脊椎骨,而是帮助开发重量级的javascript应用的框架。

主要提供了3个东西:1、models(模型) 2、collections(集合) 3、views(视图)

backbone.js文件本身很小,压缩后只有5.3KB,作为一个框架级别的核心JS文件,这个数字很可怕。

除此之外,这个JS还必须依赖于另一个JS文件:underscore.js(包含许多工具方法,集合操作,js模板等等)。

简介

用Backbone.Model表示应用中所有数据,models中的数据可以创建、校验、销毁和保存到服务端。

当models中值被改变时自动触发一个"change"事件、所有用于展示models数据的views都会侦听到这个事件,然后进行重新渲染。

Backbone.Collection和我们平时接触的JAVA集合类相似,具有增加元素,删除元素,获取长度,排序,比较等一系列工具方法,说白了就是一个保存models的集合类。

Backbone.View中可以绑定dom el和客户端事件。页面中的html就是通过views的render方法渲染出来的,当新建一个view的时候通过要传进一个model作为数据,例如:

  1. var view = new EmployeeView({model:employee});
var view = new EmployeeView({model:employee});

也就是说model就是以这种方式和view进行关联的。

特点

创建models或者views的语法:extends,相当于类继承

models的创建,销毁,校验等一系列改变都会触发相应的事件

示例

需求:用backbone.js和jquery实现一个可编辑的员工信息表格。

功能:1、录入员工信息。2、删除员工信息。3、双击表格可对员工信息进行修改。4、能对员工信息进行有效性校验。5、能对员工信息进行持久化。

设计:

用Employee类(继承自Backbone.Model)表示员工信息,包含ID、姓名、性别、年龄和职位字段。

  1. window.Employee = Backbone.Model.extend({
  2. // 模型值校验
  3. validate:function(attrs){
  4. for(var key in attrs){
  5. if(attrs[key] == ''){
  6. return key + "不能为空";
  7. }
  8. if(key == 'age' && isNaN(attrs.age)){
  9. return "年龄必须是数字";
  10. }
  11. }
  12. }
  13. });
	window.Employee = Backbone.Model.extend({
// 模型值校验
validate:function(attrs){
for(var key in attrs){
if(attrs[key] == ''){
return key + "不能为空";
}
if(key == 'age' && isNaN(attrs.age)){
return "年龄必须是数字";
}
}
}
});

声明Employee类之后就可以新增一个Employee的示例对象了:

  1. var employee = new Employee();
var employee = new Employee();

Employee类中不必声明ID、姓名等业务字段。当需要给employee设置这些信息时候,只需要调用

  1. employee.set({'id':1,'name':'Jason'});
employee.set({'id':1,'name':'Jason'});

当然,如果需要对employee的信息进行校验,需要给Employee类配置一个validate方法,这个方法的参数attrs就是set进去的json数据。这样,当employee里面的数据每次发生改变的时候都会先调用这个validate方法。

Model类定义好之后就可以开始定义集合类了,在集合类里面可以对里面的每个Model进行增加,删除等一系列操作,还可以调用fetch方法从server端获取集合的初始值。

  1. window.EmployeeList = Backbone.Collection.extend({
  2. model : Employee,
  3. // 持久化到本地数据库
  4. localStorage: new Store("employees"),
  5. });
  6. window.Employees = new EmployeeList();
	window.EmployeeList = Backbone.Collection.extend({
model : Employee,
// 持久化到本地数据库
localStorage: new Store("employees"), });
window.Employees = new EmployeeList();

设置 localStorage属性后Employees里面的数据自动会同步保存到本地数据库里面,每当调用Employees.fetch()后又会从localStorage里面恢复数据。

View类主要负责一切和界面相关的工作,比如绑定html模板,绑定界面元素的事件,初始的渲染,模型值改变后的重新渲染和界面元素的销毁等:

  1. window.EmployeeView = Backbone.View.extend({
  2. tagName : 'tr',
  3. template : _.template($('#item-template').html()),
  4. events : {
  5. "dblclick td" : "edit",
  6. "blur input,select" : "close",
  7. "click .del" : "clear",
  8. },
  9. initialize : function(){
  10. // 每次更新模型后重新渲染
  11. this.model.bind('change', this.render, this);
  12. // 每次删除模型之后自动移除UI
  13. this.model.bind('destroy', this.remove, this);
  14. },
  15. setText : function(){
  16. var model = this.model;
  17. this.input = $(this.el).find('input,select');
  18. this.input.each(function(){
  19. var input = $(this);
  20. input.val(model.get(input.attr("name")));
  21. });
  22. },
  23. close: function(e) {
  24. var input = $(e.currentTarget);
  25. var obj = {};
  26. obj[input.attr('name')] = input.val();
  27. this.model.save(obj);
  28. $(e.currentTarget).parent().parent().removeClass("editing");
  29. },
  30. edit : function(e){
  31. // 给td加上editing样式
  32. $(e.currentTarget).addClass('editing').find('input,select').focus();
  33. },
  34. render: function() {
  35. $(this.el).html(this.template(this.model.toJSON()));
  36. // 把每个单元格的值赋予隐藏的输入框
  37. this.setText();
  38. return this;
  39. },
  40. remove: function() {
  41. $(this.el).remove();
  42. },
  43. clear: function() {
  44. this.model.destroy();
  45. }
  46. });
window.EmployeeView = Backbone.View.extend({
tagName : 'tr',
template : _.template($('#item-template').html()),
events : {
"dblclick td" : "edit",
"blur input,select" : "close",
"click .del" : "clear",
},
initialize : function(){
// 每次更新模型后重新渲染
this.model.bind('change', this.render, this);
// 每次删除模型之后自动移除UI
this.model.bind('destroy', this.remove, this);
},
setText : function(){
var model = this.model;
this.input = $(this.el).find('input,select');
this.input.each(function(){
var input = $(this);
input.val(model.get(input.attr("name")));
});
},
close: function(e) {
var input = $(e.currentTarget);
var obj = {};
obj[input.attr('name')] = input.val();
this.model.save(obj);
$(e.currentTarget).parent().parent().removeClass("editing");
},
edit : function(e){
// 给td加上editing样式
$(e.currentTarget).addClass('editing').find('input,select').focus();
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
// 把每个单元格的值赋予隐藏的输入框
this.setText();
return this;
},
remove: function() {
$(this.el).remove();
},
clear: function() {
this.model.destroy();
}
});

这个类里面的代码比较多,但主要和界面的渲染有关。一个EmployeeView对象对应table里面的一个tr元素。每次new一个EmployeeView对象的时候都会先调用initialize方法,这个方法里面绑定的事件确保了tr元素对应的model值每次发生改变或者被删除时都会同步到界面。也就是说当每次操作界面对数据进行修改后都是先把当前的变更保存到view绑定的model对象里面,然后model里面的事件机制会自动触发一个"change"事件对界面进行修改。

template中使用的方法_.template($('#item-template').html())是前面提到的underscore.js中提供一个工具方法,可以通过界面的HTML模板和一个JSON生成动态的HTML,说白了就是把JSON里面的值填充到HTML模板中对应的占位符里面去,牛X的是HTML模板里面支持一些常用的逻辑表达式如if,else,foreach等:

  1. <script type="text/template" id="item-template">
  2. <td><%= eid %></td>
  3. <td class="username">
  4. <div class="display"><%= username %></div>
  5. <div class="edit"><input class="username" name="username"></input></div>
  6. </td>
  7. <td class="sex">
  8. <div class="display"><%= sex=="1" ? "女":"男" %></div>
  9. <div class="edit">
  10. <select name="sex" class="sex" style="width:45px">
  11. <option value="0">男</option><option value="1">女</option>
  12. </select>
  13. </div>
  14. </td>
  15. <td class="age">
  16. <div class="display"><%= age %></div>
  17. <div class="edit">
  18. <input class="age" name="age"></input>
  19. </div>
  20. </td>
  21. <td class="position">
  22. <div class="display"><%= position %></div>
  23. <div class="edit">
  24. <input class="position" name="position"></input>
  25. </div>
  26. </td>
  27. <td>
  28. <a href="#" class="del">删除</a>
  29. </td>
  30. </script>
	    <script type="text/template" id="item-template">
<td><%= eid %></td>
<td class="username">
<div class="display"><%= username %></div>
<div class="edit"><input class="username" name="username"></input></div>
</td>
<td class="sex">
<div class="display"><%= sex=="1" ? "女":"男" %></div>
<div class="edit">
<select name="sex" class="sex" style="width:45px">
<option value="0">男</option><option value="1">女</option>
</select>
</div>
</td>
<td class="age">
<div class="display"><%= age %></div>
<div class="edit">
<input class="age" name="age"></input>
</div>
</td>
<td class="position">
<div class="display"><%= position %></div>
<div class="edit">
<input class="position" name="position"></input>
</div>
</td>
<td>
<a href="#" class="del">删除</a>
</td>
</script>

setText方法主要负责把model里面的数据设置到每个tr里面的隐藏输入域里面。

close方法被绑定到了input和select元素的blur事件中。当用户对单元格数据进行修改后都会把鼠标点击到界面其他地方然后输入框会自动隐藏并且把修改的数据显示在表格上面。close方法首先从当前被编辑的元素中拿到最新值,然后封装成一个对象,调用model的save方法后首先执行model的validate方法,如果校验通过则保存到本地存储并触发"change"事件。

最后还需要一个主界面View,这个View主要绑定了界面中的录入表单的“增加”按钮事件,Employees的相关事件以及页面初始化时从本地存储中恢复数据:

  1. window.AppView = Backbone.View.extend({
  2. el : $("#app"),
  3. events : {
  4. "click .#add-btn" : "createOnEnter"
  5. },
  6. // 绑定collection的相关事件
  7. initialize: function() {
  8. Employees.bind('add', this.addOne, this);
  9. // 调用fetch的时候触发reset
  10. Employees.bind('reset', this.addAll, this);
  11. Employees.fetch();
  12. },
  13. createOnEnter : function(e) {
  14. var employee = new Employee();
  15. var attr = {};
  16. $('#emp-form input,#emp-form select').each(function(){
  17. var input = $(this);
  18. attr[input.attr('name')] = input.val();
  19. });
  20. employee.bind('error',function(model,error){
  21. alert(error);
  22. });
  23. // set方法中会自动调用model的validate方法进行校验,如果不通过则返回false
  24. if(employee.set(attr)){
  25. Employees.create(employee);
  26. }
  27. },
  28. addOne : function(employee){
  29. employee.set({"eid":employee.get("eid")||Employees.length});
  30. employee.bind('error',function(model,error){
  31. alert(error);
  32. });
  33. var view = new EmployeeView({model:employee});
  34. $(".emp-table tbody").append(view.render().el);
  35. },
  36. addAll : function(){
  37. Employees.each(this.addOne);
  38. }
  39. });
window.AppView = Backbone.View.extend({
el : $("#app"),
events : {
"click .#add-btn" : "createOnEnter"
},
// 绑定collection的相关事件
initialize: function() {
Employees.bind('add', this.addOne, this);
// 调用fetch的时候触发reset
Employees.bind('reset', this.addAll, this);
Employees.fetch();
},
createOnEnter : function(e) {
var employee = new Employee();
var attr = {};
$('#emp-form input,#emp-form select').each(function(){
var input = $(this);
attr[input.attr('name')] = input.val();
});
employee.bind('error',function(model,error){
alert(error);
});
// set方法中会自动调用model的validate方法进行校验,如果不通过则返回false
if(employee.set(attr)){
Employees.create(employee);
}
},
addOne : function(employee){
employee.set({"eid":employee.get("eid")||Employees.length});
employee.bind('error',function(model,error){
alert(error);
});
var view = new EmployeeView({model:employee});
$(".emp-table tbody").append(view.render().el);
},
addAll : function(){
Employees.each(this.addOne);
}
});

initialize方法中绑定了Employees的add和reset事件,也就是说每当往Employees中添加一个model的时候都会调用AppView的addOne方法,这个方法主要绑定了model的error事件以及把EmployeeView生成的html插入到界面中的合适位置。

OK,万事俱备,只欠启动,整个应用的初始化方法就是AppView的initialize方法,因此只需要新建一个AppView就可以了:

  1. window.App = new AppView();
window.App = new AppView();

整个示例的JS代码很少,加上注释只有100行左右,感兴趣的可以下载看看。由于示例使用到了本地存储,所以不要用IE运行示例,你懂的。

[转]backbone.js 初探的更多相关文章

  1. backbone.js初探(转)

    BackBone是JavaScript frameworks for creating MVC-like web applications,最近流行的用来建立单页面web application的工具 ...

  2. MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录

    注:文章内容都是摘录性文字,自己阅读的一些笔记,方便日后查看. MVC MVC(Model-View-Controller),M 是指业务模型,V 是指用户界面,C 则是控制器,使用 MVC 的目的是 ...

  3. Backbone.js应用基础

    前言: Backbone.js是一款JavaScript MVC应用框架,强制依赖于一个实用型js库underscore.js,非强制依赖于jquery:其主要组件有模型,视图,集合,路由:与后台的交 ...

  4. 我对Backbone.js的一些认识

    backbone.js已经不是当前最流行的前端框架了,但是对于我而言,依然具有比较好的学习价值.虽然目前来说,react,vue等mvvm框架非常火热,但是感觉自身还不到去使用这种框架的层次.这些技术 ...

  5. Backbone.js学习之Backbone.View(视图)

    Backbone.js为复杂WEB应用程序提供模型(models).集合(collections).视图(views)的结构.其中模型用于绑定键值数据和自定义事件:集合附有可枚举函数的丰富API: 视 ...

  6. 前端mvc框架backbone.js入门[转]

    原文地址:http://www.cnblogs.com/zhjh256/p/6083618.html 关于backbone.js的优缺点,这里就不详谈了,网上关于这方面的讨论很多了,而且各种框架之所以 ...

  7. Backbone.js

    Backbone.js是一套JavaScript框架與RESTful JSON的應用程式介面.也是一套大致上符合MVC架構的編程範型.Backbone.js以輕量為特色,只需依賴一套Javascrip ...

  8. 用Backbone.js教程系列的链接

    整理了一下用Backbone.js系列教程链接. Backbone.js入门教程 用Backbone.js创建一个联系人管理系统(一) 用Backbone.js创建一个联系人管理系统(二) 用Back ...

  9. 用Backbone.js创建一个联系人管理系统(五)

    原文: Build a Contacts Manager Using Backbone.js: Part 5 这是这系列教程最后一部分了. 之前所有的增删改都在前端完成. 这部分我们要把Contact ...

随机推荐

  1. 值得 Web 开发人员学习的20个 jQuery 实例教程

    这篇文章挑选了20个优秀的 jQuery 实例教程,这些 jQuery 教程将帮助你把你的网站提升到一个更高的水平.其中,既有网站中常用功能的的解决方案,也有极具吸引力的亮点功能的实现方法,相信通过对 ...

  2. ProgressBar.js – 漂亮的响应式 SVG 进度条

    ProgressBar.js 是一个借助动态 SVG 路径的漂亮的,响应式的进度条效果.使用 ProgressBar.js 可以很容易地创建任意形状的进度条.这个 JavaScript 库提供线条,圆 ...

  3. Walkway.js – 用线条制作简约的 SVG 动画

    Walkway.js 是一个使用线条和路径元素组成 SVG 动画图像的简单方法.只需根据提供的配置对象创建一个新的 Walkway 实例就可以了.这种效果特别适合那些崇尚简约设计风格的网页.目前, W ...

  4. Webpack - CommonJs & AMD 模块打包器

    Webpack 是一个 CommonJs & AMD 模块打包器.可以把你的 JavaScript 代码分离为多个包,在需要的时候进行加载,支持预处理文件,例如 json, jade, cof ...

  5. JavaScript中的各种变量提升(Hoisting)

    首先纠正下,文章标题里的 “变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确.因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升( ...

  6. CAShaperLayer的应用

    关于CAShapeLayer的一些实用案例和技巧 实现遮罩 音量大小动态改变的控件 圆形进度条 iOS 利用CAShapeLayer的FillRule属性生成一个空心遮罩的layer fillrule ...

  7. Ubuntu下使用Git和GitHub

    刚刚学习git和github,网上的知识太杂太乱.照着折腾了很长的时间,都没有搞出个结果,心里十分痒痒,最后终于在github上看到成果.本文适合刚刚接触github但是急于想看到效果的同学,当然gi ...

  8. 【代码笔记】iOS-点击搜索按钮,或放大镜后都会弹出搜索框

    一, 效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> #import "CLHSearchBar.h ...

  9. View的onSaveInstanceState和onRestoreInstanceState过程分析

    为什么要介绍这2个方法呢?这是因为在我们的开发中最近遇到了一个很诡异的bug.大体是这样的:在我们的ViewPager中 有2页的root view都是ScrollView,我们在xml里面都用了an ...

  10. 详解 Spotlight on Unix 监控Linux服务器

    1.安装 Spotlight on Unix 下载地址:http://yunpan.cn/QNWyEEvNS4xc9  访问密码 1c7d 傻瓜安装 2.配置spotlight登陆用户,注意spotl ...