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


Posted in Javascript onFebruary 14, 2016

什么是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。这种结构在后端是非常清晰且易实现的

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

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源码结构

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

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

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

集合 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,传入的属性会被自动转换为适合的模型类型。

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

视图 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。 --官网

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

扩展方法 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的功能。

Javascript 相关文章推荐
根据地区不同显示时间的javascript代码
Aug 13 Javascript
使用js 设置url参数
Jul 08 Javascript
jQuery实现的类似淘宝网站搜索框样式代码分享
Aug 24 Javascript
jQuery实现标题有打字效果的焦点图代码
Nov 16 Javascript
JS中使用变量保存arguments对象的方法
Jun 03 Javascript
jQuery中的100个技巧汇总
Dec 15 Javascript
浅谈js中同名函数和同名变量的执行问题
Feb 12 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
Sep 14 Javascript
js中实例与对象的区别讲解
Jan 21 Javascript
mpvue开发音频类小程序踩坑和建议详解
Mar 12 Javascript
Node.js 中判断一个文件是否存在
Aug 24 Javascript
vue 动态添加class,三个以上的条件做判断方式
Nov 02 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
Feb 14 #Javascript
Node.js 条形码识别程序构建思路详解
Feb 14 #Javascript
jQuery插件支持同一页面被多次调用
Feb 14 #Javascript
JavaScript中通过提示框跳转页面的方法
Feb 14 #Javascript
JavaScript中关联原型链属性特性
Feb 13 #Javascript
JavaScript操作class和style样式代码详解
Feb 13 #Javascript
javascript实现查找数组中最大值方法汇总
Feb 13 #Javascript
You might like
PHP格式化显示时间date()函数代码
2018/10/03 PHP
PHP接入微信H5支付的方法示例
2019/10/28 PHP
用javascript实现画板的代码
2007/09/05 Javascript
用户注册常用javascript代码
2009/08/29 Javascript
jQuery .tmpl(), .template()学习资料小结
2011/07/18 Javascript
jquery实现带复选框的表格行选中删除时高亮显示
2013/08/01 Javascript
Jquery.Form 异步提交表单的简单实例
2014/03/03 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
jQuery扩展_动力节点Java学院整理
2017/07/05 jQuery
微信小程序实现tab和swiper切换结合效果
2020/07/17 Javascript
scrapyd schedule.json setting 传入多个值问题
2019/08/07 Javascript
js实现带积分弹球小游戏
2020/07/21 Javascript
[27:28]Ti4 冒泡赛第二天 iG vs NEWBEE 1
2014/07/15 DOTA
Python生成随机密码
2015/03/10 Python
jupyter notebook引用from pyecharts.charts import Bar运行报错
2020/04/23 Python
Python实现账号密码输错三次即锁定功能简单示例
2019/03/29 Python
关于matplotlib-legend 位置属性 loc 使用说明
2020/05/16 Python
Ubuntu权限不足无法创建文件夹解决方案
2020/11/14 Python
python3 re返回形式总结
2020/11/20 Python
python Scrapy爬虫框架的使用
2021/01/21 Python
css3 transform及原生js实现鼠标拖动3D立方体旋转
2016/06/20 HTML / CSS
详解HTML5新增标签
2017/11/27 HTML / CSS
Bibloo匈牙利:女装、男装、童装及鞋子和配饰
2019/04/14 全球购物
俄罗斯极限运动网上商店:Board Shop №1
2020/12/18 全球购物
如何开启linux的ssh服务
2015/02/14 面试题
大学生优秀的自我评价分享
2013/10/22 职场文书
养成教育经验材料
2014/05/26 职场文书
我为党旗添光彩演讲稿
2014/09/13 职场文书
2014公司年终工作总结
2014/12/19 职场文书
检讨书范文500字
2015/01/28 职场文书
小学教师个人总结
2015/02/05 职场文书
世界名著读书笔记
2015/06/25 职场文书
毕业典礼主持词
2015/06/29 职场文书
因个人工作失误检讨书
2019/06/21 职场文书
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python
python 爬取天气网卫星图片
2021/06/07 Python