By:软件11 王思伦 2013-10-4

Backbone简述:

Backbone基于MVC架构,用于开发重量级Javascript应用的框架。

如上文所述,Backbone包含多种类,但主要包含了三种:Backbone.Model, Backbone.Collection, Backbone.View。

它能让你像写 java 代码一些写 js 代码,定义类,类的属性以及方法。更重要的是它能够优雅的把原本无逻辑的 javascript 代码进行组织,并且提供数据和逻辑相互分离的方法,减少代码开发过程中的数据和逻辑混乱。

另外backbone必须要依赖另一个文件underscore.js(包含许多工具方法,集合操作,js模板等等),我在做backbone测试的时候就因为没有包含underscore.js搞得无法显示一头雾水。

Backbone主体介绍:

Backbone.Model表示应用中所有数据,model中的数据可以创建(new)、校验(validate)、销毁(destroy)和保存到服务端(localstorage)。当models中值被改变时自动触发一个"change"事件(Backbone.Event)、所有用于展示model数据的view都会侦听到这个事件,然后进行重新渲染(render)。

Backbone.Collection有点像JAVA集合类(list/vector),具有增加元素,删除元素,获取长度,排序,比较等一系列工具方法,简而言之是一个保存models的集合类。

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

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

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

Model

声明:

  在创建Model或者View等backbone类的时候,我们总会使用如下语句:Backbone.Model.extend 

  其中使用了extends继承model和view,因此models的创建,销毁,校验等一系列改变都会触发相应的事件

实例化:

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

  1. var employee = new Employee();  

赋值:

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

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

校验:

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

Collection

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

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

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

View

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

  1.  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模板中对应的占位符里面去,HTML模板里面还支持一些常用的逻辑表达式如if, else, foreach等。

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

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

Application:

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

 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插入到界面中的合适位置。

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

window.App = new AppView();

参考资料:http://weakfi.iteye.com/blog/1391990

Backbone实践案例的更多相关文章

  1. DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能

    DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己 ...

  2. 微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io

    原文:微服务实战(四):服务发现的可行方案以及实践案例 - DockOne.io 这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三 ...

  3. - 反编译 AndroidKiller 逆向 实践案例 MD

    目录 目录 反编译 AndroidKiller 逆向 实践案例 MD AndroidKiller 简介 插件升级 基本使用 实践案例 修改清单文件 打印 debug 级别的日志 方式一:直接代理 Lo ...

  4. 《SaltStack技术入门与实践》—— 实践案例 <中小型Web架构>3 Memcached配置管理

    实践案例 <中小型Web架构>3 Memcached配置管理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Memcached介绍 Me ...

  5. Hadoop家族学习路线、实践案例

    作者:Han Hsiao链接:https://www.zhihu.com/question/19795366/answer/24524910来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  6. 爬虫学习(十二)——bs4实践案例

    实践项目————诗词名句网<三国演义>小说爬取 import osimport reimport timeimport urllib.requestimport urllib.parsef ...

  7. 数据库周刊30丨数据安全法草案将亮相;2020数据库产业报告;云南电网上线达梦;达梦7误删Redo Log;Oracle存储过程性能瓶颈;易鲸捷实践案例……

    摘要:墨天轮数据库周刊第30期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.数据安全法草案即将亮相:将确立数据分级分类管理.应急处置制度[摘要]数据安全法草案即将在本 ...

  8. redis入门到精通系列(二):redis操作的两个实践案例

    在前面一篇博客中我们已经学完了redis的五种数据类型操作,回顾一下,五种操作类型分别为:字符串类型(string).列表类型(list).散列类型(hash).集合类型(set).有序集合类型(so ...

  9. [.NET领域驱动设计实战系列]专题七:DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能

    一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己的订单状态看到店家已经发货.从上面的业务逻辑可以看出,当用户 ...

随机推荐

  1. Beta 冲刺 (7/7)

    Beta 冲刺 (7/7) 队名:洛基小队 峻雄(组长) 已完成:人物释放技能部分的实现 后两天计划:整合脚本,测试内容 剩余任务:整合各部分脚本 困难:尽快完善整合出β版的内容 非易 已完成:商店功 ...

  2. 根据进程ID查找运行程序目录

    查看进程ID [root@hadoop03 openresty]# netstat -nltp 进入/proc目录查找相应进程ID目录并进入此目录 [root@hadoop03 usr]# cd /p ...

  3. MySQL数据库常用操作和技巧

    MySQL数据库可以说是DBA们最常见和常用的数据库之一,MySQL的广泛应用,也使更多的人加入到学习它的行列之中.下面是老MySQL DBA总结的MySQL数据库最常见和最常使用的一些经验和技巧,分 ...

  4. 使用<button></button>标签

    使用<button></button>标签一定要记住给它设置type,因为它默认的type=“submit”,会提交表单,设置如下 <button type=" ...

  5. Invoking "cmake" failed报错处理

    运行$ pip install -U rosdep rosinstall_generator wstool rosinstall six vcstools运行完成后再重新编译

  6. JS模拟下拉框select

    最近做的一个项目有下拉框 同事都是用的是美化控件,但是用美化控件当然是好 但是网上找的一个控件不知道扩展性怎么样?对以后的维护会不会造成有影响?比如我想增加一个功能或者减少一个功能会不会影响?还有就是 ...

  7. HDU1754

    https://vjudge.net/contest/66989#problem/B 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜 ...

  8. HDU 1421 搬寝室(经典DP,值得经常回顾)

    搬寝室 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status D ...

  9. memcpy、memmove、memset、memchr、memcmp、strstr详解

    第一部分 综述 memcpy.memmove.memset.memchr.memcmp都是C语言中的库函数,在头文件string.h中.memcpy和memmove的作用是拷贝一定长度的内存的内容,m ...

  10. STM32驱动ILI9341控制器控制TFTLCD显示

    STM32驱动ILI9341控制器控制TFTLCD显示 一.用STM32控制TFTLCD显示的编程方法,在编程驱动TFTLCD液晶显示器之前,我们先熟悉以下概念: 1.色彩深度,这是一个与TFTLCD ...