讲解JavaScript的Backbone.js框架的MVC结构设计理念

什么是Backbone.js?
Backbone.js是十大JS框架之首,Backbone.js 是一个重量级js  MVC 应用框架,也是js MVC框架的鼻祖。它通过Models数据模型进行键值绑定及custom事件处理,通过模型集合器Collections提供一套丰富的API用于枚举功能,通过视图Views来进行事件处理及与现有的Application通过JSON接口进行交互。

简而言之,Backbone是实现了web前端MVC模式的js库

什么是MVC?
MVC:后端服务器首先(过程1)通过浏览器获取页面地址,对网址进行解析,得到视图View给它的一个网址,然后通过控制器controller进行解析,然后去找对应的数据(过程2),找到数据后,再将数据Model返回给控制器(过程3),控制器controller再对数据进行加工,最后返回给视图(过程4),即更新视图View。这种结构在后端是非常清晰且易实现的

Backbone中MVC的机制
Backbone将数据呈现为模型, 你可以创建模型、对模型进行验证和销毁,甚至将它保存到服务器。 当UI的变化引起模型属性改变时,模型会触发"change"事件; 所有显示模型数据的视图会接收到该事件的通知,继而视图重新渲染。 你无需查找DOM来搜索指定id的元素去手动更新HTML。 — 当模型改变了,视图便会自动变化。———百度百科

模式:一种解决问题的通用方法

—设计模式:工厂模式、适配器模式和观察者模式
 —框架模式:MVC、MVP、MVVM
控制器:通过控制器来连接视图与模型。

MVC模式的思想:

就是把模型与视图分离,通过控制器来连接他们
服务器端MVC模式非常容易实现
Model:模型即数据,模型 是所有 js 应用程序的核心,包括交互数据及相关的大量逻辑: 转换、验证、计算属性和访问控制。你可以用特定的方法扩展 Backbone.Model

View:即你在页面上所能看到的视图。每一个单一的数据模型对应一个视图View

web页面本身就是一个很大的view,不太容易做到分离操作,backbone.js适合复杂的大型开发,并为我们解决了这些难题

backbone的模块
backbone有如下几个模块:

  • Events:事件驱动模块
  • Model:数据模型
  • Collection:模型集合器
  • Router:路由器(对应hash值)
  • History:开启历史管理
  • Sync:同步服务器方式
  • View:视图(含事件行为和渲染页面 相关方法)

集合器Collection是对单独的数据模型进行统一控制

直接创建对象
Backbone依赖于Underscore.js, DOM 处理依赖于 Backbone.View 和 jQuery ,因此,在引入Backbone.js之前,Underscore.js必须在它之前引入,而jQuery也最好一并引入,最后再引入Backbone.js

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <script src = "jquery-2.0.3.min.js"></script>
  <script src = "underscore-min.js"></script>
  <script src = "backbone.js"></script>

</head>
<body>
  var model = new Backbone.Model();
  var col = new Backbone.Collection();
  var view = new Backbone.View();
</body>

new后面是一个构造函数,而Backbone是作为构造函数的命名空间来使用的

Model模块

Backbone.Model.extend(properties, [classProperties])

Backbone通过extend来扩展实例方法和静态方法:

<script type="text/javascript">
  //extend接收的第一个参数是json格式的字符串,用来扩展实例方法
  //第二个参数也是json格式的字符串,用来扩展静态方法
  var M = Backbone.Model.extend({
    abc : function(){  //实例方法
      alert("hello backbone");
    }
  },{
    def : function(){ //静态方法
      alert("hi");
    }
  });

  var model = new M;
  model.abc();//实例方法要用实例对象来访问
  M.def();//静态方法直接挂载到了构造函数上,可以通过构造函数来直接访问
</script>

静态方法其实就是多了一个命名空间。以上是给构造函数添加实例方法和静态方法

 var M = Backbone.Model.extend({})

通过extend来为模型的构造函数扩展方法,M就是扩展之后的构造函数

继承

<script type="text/javascript">
  //继承
  var Mod = backbone.Model.extend({
    abc : function(){
      alert(123);
    }
  });

  var ChildMod = Mod.extend();

  var model = new ChildMod;
  model.abc();//子类继承了父类的方法
</script>

Backbone源码结构

1:  (function() {

2:      Backbone.Events        // 自定义事件

3:      Backbone.Model        // 模型构造函数和原型扩展

4:      Backbone.Collection    // 集合构造函数和原型扩展

5:      Backbone.Router        // 路由配置器构造函数和原型扩展

6:      Backbone.History        // 路由器构造函数和原型扩展

7:      Backbone.View            // 视图构造函数和原型扩展

8:      Backbone.sync            // 异步请求工具方法

9:      var extend = function (protoProps, classProps) { ... } // 自扩展函数

10:      Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend; // 自扩展方法

11:  }).call(this);
JS MVC职责划分
M 模型

业务模型:业务逻辑、流程、状态、规则
(核心)数据模型:业务数据、数据校验、增删改查(AJAX)
V 视图

(核心)视图:定义、管理、配置
模板:定义、配置、管理
组件:定义、配置、管理
(核心)用户事件配置、管理
用户输入校验、配置、管理
C 控制器/分发器

(核心)事件分发、模型分发、视图分发
不做数据处理、业务处理,即业务无关
扩展:权限控制、异常处理等
C是JSMVC框架的核心,实现集中式配置和管理,可以有多个控制器
工具库

主要是异步请求、DOM操作,可以依赖于jQuery等

Model指的是一条一条的数据,而集合Collection指的是对Model中的多条数据进行管理。

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

对象赋值的方法
1、直接定义,设置默认值

 Trigkit = Backbone.Model.extend({
       initialize : function () {
         alert('hi!');
       },
       defaults:{
         age : '22',
         profession : 'coder'
       }
     });
    var coder = new Trigkit;
    alert(coder.get('age'));//22

2、 赋值时定义

<script type="text/javascript">
   Trigkit = Backbone.Model.extend({
     initialize : function () {
       alert('hi!');
     }
   });
   var t = new Trigkit;
   t.set({name :'huang',age : '10'});
   alert(t.get('name'));
</script> 

对象中的方法

<script type="text/javascript" src="Underscore.js"></script>
<script type="text/javascript" src="backbone-1.1.2.js"></script>
<script type="text/javascript">
    var Trigkit4 = Backbone.Model.extend({
      initialize : function () {
        alert("hello world!");
      },
      defaults : {
        name : 'zhangsan',
        age : 21
      },
      aboutMe: function () {
        return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁';
      }
    });
    var t = new Trigkit4;
    alert(t.aboutMe());
  </script>

当模型实例化时,他的initialize方法可以接受任意实例参数,其工作原理是backbone模型本身就是构造函数,所以可以使用new生成实例:

var User = Backbone.Model.extend({
  initialize: function (name) {
    this.set({name: name});
  }
});
var user = new User('trigkit4');
alert(user.get('name'), 'trigkit4');//trigkit4

看下backbone的源码:

var Model = Backbone.Model = function(attributes, options) {
  var attrs = attributes || {};
  options || (options = {});
  this.cid = _.uniqueId('c');
  this.attributes = {};
  if (options.collection) this.collection = options.collection;
  if (options.parse) attrs = this.parse(attrs, options) || {};
  attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
  this.set(attrs, options);
  this.changed = {};
  this.initialize.apply(this, arguments);
 };

 initialize: function(){},//initialize是默认的空函数

Model 的事件绑定
为了能及时更新view,我们需要通过事件绑定机制来处理和响应用户事件:

  <script type="text/javascript">
    var Task = Backbone.Model.extend({
      initialize: function () {
        this.on("change:name", function (model) {
          alert("my name is : " + model.get("name"));
        });
      }
    });

    var task = new Task({ name:"oldname", state:"working"});
    task.set({name:"trigkit"});
//    object.on(event, callback, [context])
  </script>
</head>

关于事件绑定,有on,off,trigger,once,listenTo,stopListening,listenToOnce等方法,具体参照:http://documentcloud.github.io/backbone/#Events

集合 Collection
Backbone.Collection就是一个Model对象的有序集合。因为Model是一条数据记录,也就是说,Collection相当于是一个数据集。具有增加元素,删除元素,获取长度,排序,比较等一系列工具方法,说白了就是一个保存models的集合类。

<script type="text/javascript">
  var Book = Backbone.Model.extend({
    defaults : {
      title:'default'
    },

    initialize: function(){

       alert('hello backbone!');//弹出3次
    }
  });

  BookShelf = Backbone.Collection.extend({

    model : Book

  });

  var book1 = new Book({title : 'book1'});

  var book2 = new Book({title : 'book2'});

  var book3 = new Book({title : 'book3'});

  //var bookShelf = new BookShelf([book1, book2, book3]); //注意这里面是数组,或者使用add

  var bookShelf = new BookShelf;

  bookShelf.add(book1);
  bookShelf.add(book2);
  bookShelf.add(book3);
  bookShelf.remove(book3);

  //基于underscore这个js库,还可以使用each的方法获取collection中的数据
  bookShelf.each(function(book){

    alert(book.get('title'));

  });
</script>

collection.model覆盖此属性来指定集合中包含的模型类。可以传入原始属性对象(和数组)来 add, create,和 reset,传入的属性会被自动转换为适合的模型类型。

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

view.$el:一个视图元素的缓存jQuery对象。 一个简单的引用,而不是重新包装的DOM元素。
一个简单的View:

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="jquery-1.9.1.min.js"></script>
  <script type="text/javascript" src="Underscore.js"></script>
  <script type="text/javascript" src="backbone-1.1.2.js"></script>
  <script type="text/javascript">

      var TestView = Backbone.View.extend({ //创建一个view,其实就是一个HTML的DOM节点
        initialize: function() {
          this.render();
        },
        render: function() { // 渲染方法
          this.$el.html('Hello World'); //this.el就是HTML节点,通过jQuery的html方法填充内容
          return this;
        }
      });

      $(function () {
        var test = new TestView({el: $('#body')});// 以目标节点为el参数,创建一个view的实例,render函数将会被自动调用并将渲染结果填充到el中
        //test.render(); // 如果没在 initialize 里调用 render 的话,就需要在这里调用一次
      });
  </script>
</head>
<body>
<div id="body"></div>
</body>

elview.el所有的视图都拥有一个 DOM 元素(el 属性),即使该元素仍未插入页面中去。 视图可以在任何时候渲染,然后一次性插入 DOM 中去,这样能尽量减少 reflows 和 repaints 从而获得高性能的 UI 渲染。 this.el 可以从视图的 tagName, className, id 和 attributes 创建,如果都未指定,el 会是一个空 div。 --官网

扩展方法 extend
模型、集合、视图、路由器都有一个extend方法,用于扩展原型属性和静态属性,创建自定义的模型、集合、视图、路由器类。

Backbone.Model.extend
Backbone.Model.extend(properties, [classProperties])

要创建自己的 Model 类,你可以扩展 Backbone.Model 并提供实例 properties(属性) , 以及可选的可以直接注册到构造函数的classProperties(类属性)。

Backbone.View.extend
Backbone.View.extend(properties, [classProperties])

开始创建自定义的视图类。 通常我们需要重载 render 函数,声明 events, 以及通过 tagName, className, 或 id 为视图指定根元素。 Backbone.View通过绑定视图的 render 函数到模型的 "change" 事件 — 模型数据会即时的显示在 UI 中。

Backbone.Collection.extend
Backbone.Collection.extend(properties, [classProperties])

通过扩展 Backbone.Collection 创建一个 Collection 类。实例属性参数 properties 以及 类属性参数 classProperties 会被直接注册到集合的构造函数。

Backbone.Router.extend
Backbone.Router.extend(properties, [classProperties])

开始创建一个自定义的路由类。当匹配了 URL 片段便执行定义的动作,并可以通过 routes 定义路由动作键值对。

Router与controller
controller是Backbone 0.5以前的叫法,现在改名叫Router了。

Backbone.Router 为客户端路由提供了许多方法,并能连接到指定的动作(actions)和事件(events)。
页面加载期间,当应用已经创建了所有的路由,需要调用 Backbone.history.start()

查看下面示例:

<script type="text/javascript">
    var AppRouter = Backbone.Router.extend({
      routes: {
        "index" : "index",
        "task/:id": "task",
        "*acts": "tasklist"
      },
      index: function() {
        alert("index");
      },
      tasklist: function(action) {
        alert(action);
      },
      task: function(id) {
        alert(id);
      }
    });

    var app = new AppRouter;
    Backbone.history.start();
  </script>

在浏览器里打开页面后,在url的html后面依次加上:

#/index
#/task/1
#/test/xxxx

将分别弹出出:index, 1, test/xxxx

这就是Router的功能。

(0)

相关推荐

  • Angularjs中的事件广播 —全面解析$broadcast,$emit,$on

    Angularjs中不同作用域之间可以通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信 介绍: $broadcast的作用是将事件从父级作用域传播至子级作用域,包括自己.格式如下:$broadcast(eventName,args) $emit的作用是将事件从子级作用域传播至父级作用域,包括自己,直至根作用域.格式如下:$emit(eventName,args) $on用于在作用域中监控从子级或父级作用域中传播的事件以及相应的数据.格式如下:$on(event,dat

  • 超级简单实现JavaScript MVC 样式框架

    介绍 使用过JavaScript框架(如AngularJS, Backbone 或者Ember)的人都很熟悉在UI(用户界面,前端)中mvc的工作机理.这些框架实现了MVC,使得在一个单页面中实现根据需要变化视图时更加轻松,而模型-视图-控制器(mvc)的核心概念就是:处理传入请求的控制器.显示信息的视图.表示业务规则和数据访问的模型. 因此,当需要创建这样一个需要在单个页面中实现切换出不同内容的应用时,我们通常选择使用上述框架之一.但是,如果我们仅仅需要一个在一个url中实现视图切换的框架,而

  • indexedDB bootstrap angularjs之 MVC DOMO (应用示例)

    1.indexedDB(Model) -- 前端浏览器对象型数据库,一般我们后台用的数据库都是关系型数据库.那么indexeddb有什么特点呢: 首先,从字义上它是索引型数据库,从实际使用中可以体现为,它需要为表创建索引才可以根据某个字段来获取数据,而在关系型数据库中,这明显是不需要的. 其次,我不需要行列数据的转化,我只需要通过类似于数组的处理方式: 复制代码 代码如下: objectStore.push(data); 有点像是把一个json对象塞入数据库,是不是很暴力? 2.bootstra

  • Javascript MVC框架Backbone.js详解

    随着JavaScript程序变得越来越复杂,往往需要一个团队协作开发,这时代码的模块化和组织规范就变得异常重要了.MVC模式就是代码组织的经典模式. (--MVC介绍.) (1)Model Model表示数据层,也就是程序需要的数据源,通常使用JSON格式表示. (2)View View表示表现层,也就是用户界面,对于网页来说,就是用户看到的网页HTML代码. (3)Controller Controller表示控制层,用来对原始数据(Model)进行加工,传送到View. 由于网页编程不同于客

  • 12种JavaScript常用的MVC框架比较分析

    本文详细讲述了12种JavaScript常用的MVC框架.分享给大家供大家参考,具体如下: Gordon L. Hempton是西雅图的一位黑客和设计师,他花费了几个月的时间研究和比较了12种流行的JavaScript MVC框架,并在博客中总结了每种框架的优缺点,最终的结果是,Ember.js胜出. 此次比较针对的特性标准有四种,分别是: ① UI绑定(UI Bindings) ② 复合视图(Composed Views) ③ Web表现层(Web Presentation Layer) ④

  • 前端轻量级MVC框架CanJS详解

    选择正确的库 创建一个JS APP没有好的工具是很有难度的,jQuery只是操作DOM的库,没有提供任何创建APP的基础,这就是为什么我们要一个类似CanJS的专门的库. CanJS 是一个轻量级的MVC库,提供你创建一个JS APP所需的工具. CanJS 是一个轻量级的MVC库,提供你创建一个JS APP所需的工具. 它提供有MVC (Model-View-Control) 模式的基本框架,模板动态绑定, route的支持且 内存安全.同时支持 jQuery, Zepto, Mootools

  • Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块完美实现

    中午的时候发了第一篇 Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块 ,发现实现上还是有问题,有很多理解不到位的地方,晚上详细解决下了,终于实现MVC各模块按需加载了,哈皮. 上篇文章中,关于ExtJs这个玩意的评论就跟java和.Net那个好一样,既然上了贼船,就难下了,而且对于企业级的应用我个人觉得Extjs框架还是不错的,尤其是没有UI设计的团队(苦逼的程序员就兼UI吧),起码难得发现一个做的比较好的UI框架(国产的miniUI貌似看的过去,其他的就有点

  • AngularJs Javascript MVC 框架

    在6月google发布了AngularJs 1.0稳定版, 并宣称:AngularJS可以让你扩展HTML的语法,以便清晰.简洁地表示应用程序中的组件,并允许将标准的HTML作为你的模板语言,AngularJS可以通过双向数据绑定自动从拥有JavaScript对 象(模型)的UI(视图)中同步数据. 开始接触AngularJs是在4月份来到新项目组,这时AngularJs还处于0.8未稳定版,项目中已经开始使用了,并且这套框架应用到了项目整个UI端,服务端也是未稳定的web api,真心佩服团队

  • jquery.form.js框架实现文件上传功能案例解析(springmvc)

    上一篇 Bootstrap自定义文件上传下载样式(http://www.jb51.net/article/85156.htm)已经有一段时间了,一直在考虑怎么样给大家提交一篇完美的逻辑处理功能.现在我结合自己的实际工作给大家分享一下. 使用的技术有jquery.form.js框架, 以及springmvc框架.主要实现异步文件上传的同时封装对象,以及一些注意事项. 功能本身是很简单的,但是涉及到一些传递参数类型的问题.例如:jquery的ajax方法与jquery.form.js中的ajaxSu

  • 使用jQuery.form.js/springmvc框架实现文件上传功能

    使用的技术有jquery.form.js框架, 以及springmvc框架.主要实现异步文件上传的同时封装对象,以及一些注意事项. 功能本身是很简单的,但是涉及到一些传递参数类型的问题.例如:jquery的ajax方法与jquery.form.js中的ajaxSubmit方法的参数,具体细节将在下一篇博客中分享. 重点: html表格三要素: action="fileUpload/fileUpload" method="post" enctype="mul

  • AngularJs解决跨域问题案例详解(简单方法)

    首先我们做点准备说明,不然你明白我说的是啥意思别人不明白,就算别人明白了那总有人不明白,那你要说了,我的意思是这个说明必须要做了,答案是必须的,为了更好的方便大家理解嘛. 我们以两个主域名或者一个主域名+一个二级域名为例,均可演示跨域问题. 客户端 a.com 服务端 b.com或者s.a.com angularJs版本 V1.2.25 准备工作做得很充分嘛,就差把我们的编辑器是subline暴露出来了,这个一般人我是不告诉他滴. 有人嚷嚷了,这问题老早就有了,你现在提出来有啥意义呢?难不成你还

随机推荐