本文转自: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. JavaScript 开发者经常忽略或误用的七个基础知识点(转)

    JavaScript 本身可以算是一门简单的语言,但我们也不断用智慧和灵活的模式来改进它.昨天我们将这些模式应用到了 JavaScript 框架中,今天这些框架又驱动了我们的 Web 应用程序.很多新 ...

  2. 在SharePoint 2013中显示“以其他用户身份登录”

    在我新建了SharePoint 2013的网站后, 发现界面与2010有一些不同,比如缺少了“以其他用户身份登录”,这给我的测试带来很大不便. 在找了一些国外网站后,终于找到了解决方法 第一步: 找到 ...

  3. Sharepoint 2010 工作流启动时处理表单出错

    问题: Shareoint 2010 列表工作流启动时,显示“处理表单时出现严重错误”. Error Message-1: Object doesn't support property or met ...

  4. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q81-Q83)

    Question  81You are designing a custom administrative timer job for a SharePoint 2010 farm. You need ...

  5. Android 采用get方式提交数据到服务器

    首先搭建模拟web 服务器,新建动态web项目,servlet代码如下: package com.wuyudong.web; import java.io.IOException; import ja ...

  6. Mac下的快速回到桌面快捷方式

    今天突然发现一个Mac下快速回到桌面的快捷方式. command+F3 快速回到桌面. 如果想增加动画效果,快捷键是: command+shift+F3 这个功能虽然小,但是确实非常实用啊!

  7. Safari 快捷键

    标签和网页导航快捷键 8 个 切换到下一个标签页 – Control+Tab 切换到上一个标签页 – Control+Shift+Tab 向下滚动一屏 – 空格 向上滚动一屏 – Shift+空格 焦 ...

  8. array_filter、array_map、array_walk解释

    /** * array_filter 用回调函数处理数组中的各个元素, * 重点在于过滤(而不是新增)某个元素,当你处理到一个元素时, * 如果返回了false,那么这个元素将会被过滤掉.PS:保持了 ...

  9. Linux hostname对Oracle实例以及监听的影响

    在Linux平台中,对hostname的修改,是否对ORACLE数据库实例或监听进程有影响呢?如果有影响,又要如何解决问题呢?另外/etc/hosts下相关内容的修改,是否也会影响实例或监听呢?这里涉 ...

  10. HDFS 和YARN HA 简介

    HDFS: 基础架构 1.NameNode(Master) 1)命名空间管理:命名空间支持对HDFS中的目录.文件和块做类似文件系统的创建.修改.删除.列表文件和目录等基本操作. 2)块存储管理. 使 ...