BackBone及其实例探究_动力节点Java学院整理


Posted in Javascript onJuly 14, 2017

MVC简介

基本介绍

MVC即模型(Model),视图(View)和控制(Controller),旨在实现Web系统的职能分工,具体来说就是使业务逻辑和数据显示分离。

在MVC中,视图(View)为用户提供交互,模型(Model)负责处理数据和业务逻辑,控制器(Controller)则是View与Model之间沟通的桥梁。

MVC一个很重要的标志就是,视图(View)与模型(Model)没有直接的交互,而是通过控制器(Controller)来沟通。具体地:用户通过View进行输入,Controller负责把输入传递给Model,Model处理,存取数据,然后Controller将处理的结果返回View进行展示。

优缺点

MVC架构的优势是显著的,但也存在一些缺点。

一方面,MVC能极大地降低数据与视图之间的耦合性,具有较高的可维护性和复用性,还能提高分工效率和降低生命周期的成本,从而有利于软件工程化管理。

 然而,MVC架构却不是那么容易理解,且会增加系统的复杂性,还会降低视图层访问数据层的效率,不适用于小型工程的开发。

Backbone

BackBone是一个重要的前端MVC框架,用于支持Javactript应用的重量级开发。下面将对Backbone.Events(和控制器有着密切联系)以及Backbone.Model(和模型有着密切联系)的应用进行介绍,并结合实例分析Backbone框架是如何支持前端MVC的架构的。所有的学习资料来自于BackBone官网:http://backbonejs.org/

Backbone.Events

在Backbones中,事件可以作为一个任何一个对象的模型,对象能够绑定和触发一个事件被命名的事件。 

对于一个被声明了的对象object(下文的讨论,所有的对象都以object为例),首先为object添加extend。

._extend(object,Backbone.Events);

然后为对象添加一个事件:格式为:

object.on(event,callback,[context]);

第一个参数为事件名,第二参数为事件调用时的回调函数。

以下面的事件为例:”alert”为事件名,function(msg)为回调函数,msg为触发事件时所传入的参数,与触发器中的参数一致。

object.on(“alert”,function(msg){alert(msg);});

触发object.on进行回调的是object.trigger(“alert”, ”It's an event”)。

同object.on,object.trigger第一个参数为事件名,而第二个参数传入的是object.on中回调函数所需要的参数。事件通过事件名被绑定在一个对象上。可以看到这个事件在绑定前是不需要声明的,事件能够被触发的内在联系是共同的对象和事件名。特别地,如果事件名为”all”,那么调用任何object.trigger时,都会触发object.on中的回调函数。

与标准的事件绑定相对应的,标准触发的格式为: 

object.trigger(event,[*arg]);

也可用js中类似属性的定义来绑定一个对象的多个事件,如:

object.on{
  “setup”:function_a(),
  “change”:function_b(),
  “destroy”:function_c()
}

触发相应的”setup”,”change”,和”destroy”时可以分别调用相应的function_a()等。

如果需要解除对象上一个事件的绑定,则使用object.off(event,callback,[context])函数。标准参数列表与相应的object.on一致。
具体的,以上面的”setup”:function_a()为例:

//解绑定
 object.off(“setup”,function_a);
 
 //移除所有的”setup”事件(可能绑定多个回调函数)
 object.off(“setop”);
 
 //移除所有的绑定function_a这个回调函数的事件
 object.off(function_a);
 
 //移除所有的事件
 object.off()。

如果希望事件被触发一次就解绑定,则直接使用object.once(event,callback,[context])。

使用object.listenTo(other_object, event, callback),可监听其他对象的事件,事件被触发时同样调用callback的回调函数。类似的,可使用标准的stopListenTo([other_object], [event],[callback]),进行解绑定。

 ListenTo在MVC架构中很有用,如使用视图类的对象监听Model类的数据处理事件,并进行回调(一般是对数据进行展示)。

BackBone.Model

Models是一个Javascript应用的核心。很多时候,models需要处理许多数据,以及与这些数据相关的逻辑。然而,对于javascript来说,并没有类似java那样的类的结构的存在。然而在实际应用中,却需要这样的模型结构。而BackBone.Model为js提供了很好的拓展,让javascript也能实现类的结构和功能,更准确地说,实现类似C#中的属性。下面给出官方介绍的一个简化的实例(为了简洁起见,之后所有介绍的模型都采用Model,而模型的对象都采用model):

//类似类的定义
var Model = BackBone.Model.extend({
  myData:”year2013”,
  myFunction:function(){myData = “year2014”;}
);

//类似类的实例化
var model = new Model; 

//类似对象调用成员方法
my_class.myFunction();

可以看到以上的代码就实现了类似类的结构。与传统javascript对象的属性区别在于,一个是具体的对象(只能使用一次),另一个是一个类的模型(可以被多次实例化)。

既然已经有了类似类的实例化功能,那么自然,BackBone.Model也为我们提供了类似构造函数的拓展。当实例化一个对象时,采用new Model([attributes], [options])的标准格式进行实例化。例如:

new Model({
    myData:”2013”
});

此外,经过拓展BackBone的js同C#一样,还具有属性的get和set函数。类似下面地进行调用:

var date = model.get(myData);
model.set(myData,”2014”); 

此外,BackBone.Model还为js拓展了许多模型的默认函数,不一一介绍。需要使用的时候,建议在官网http://backbonejs.org/#Model-url的Model进行查询。

BackBone实例:Todo

下面结合官网中所给出的实例Todos来看一看BackBone在前端MVC的具体应用。 

这是一个纯js实现的任务单application。

代码中设计了四个“类”来实现任务单的功能:

//Model层面,实现一条任务的数据操作
var Todo = BackBone.Model.extend({});

//Model层面,实现整个任务栏的数据操作,Collection拓展了本地存储功能
var TodoList = BackBone.Collection.extend({});

//BackBone.View.extend(),View和Controller层面
//负责接收用户操作和修改Model的数据,在render()函数中展示数据

//与Todo的Dom元素相关
var TodoView = BackBone.View.extend({});
//最顶层的UI以及控制器
var AppView = BackBone.View.extend({});

首先来分析实例中的Model,采用自下而上的分析方法:

Todo代表每一条Todo中的任务,与之相关的逻辑是其是否已经完成,需要指定其是否完成,需要初始属性done:false,另外需要设置done的函数,为此添加属性:

toggle:function(){
  this.save({done:!this.get(“done”);});
}

可以看到这个属性在数据层从逻辑上实现了View层复选框的功能。

对于TodoList,使用Collection这一Model,为的是实现的数据本地存储。

属性含有model:Todo,即低层的,实现一个任务的实例。

此外,还需要localStorage : new BackBone.LocalStorage(“todos-backbone”)。用来进行本地存储。

在数据处理方面,需要对低层的done属性进行封装,实现了done:function(),返回被改变的done的位置。

在View和Controller层面,自下而上地依次设计了下面两个“类”。

var TodoView = BackBone.View.extend({});
var AppView = BackBone.View.extend({}); 

首先,对于TodoView,设置了一系列事件的响应,TodoView在Controller层面,对于View,接收这样的事件监听:

events: {
   "click .toggle"  : "toggleDone",
   "dblclick .view" : "edit",
   "click a.destroy" : "clear",
   "keypress .edit" : "updateOnEnter",
   "blur .edit"   : "close"
}

以clear()为例,clear中调用this.model.destroy()进行数据层的处理,这就反馈到了数据层。

clear: function() {
   this.model.destroy();
}

另一方面,在初始化时,指定了TodoView对数据层的this.model添加了监听,当this.model的change事件发生,TodoView发生this.remove(render亦同),而这是表现层的内容,这样就反馈到了表现层。

initialize: function() {
   this.listenTo(this.model, 'change', this.render);
   this.listenTo(this.model, 'destroy', this.remove);
}

这样一来便完成了从View(输入) -> Controller -> Model(处理) -> Contoller -> View(展示)的MVC架构。从上面可以看到,从数据的接收,处理,返回,展示,所有过程都是自动的,且View和Model没有任何的耦合。这是标准的MVC模式。

从TodoView向上则是总体的AppView。它的逻辑行为也是类似的,亦是在视图层接收数据,通过View类特有的结构反馈到数据层,然后数据层又无耦合地将数据返回到视图层进行展示。但是作为最顶层的View和Controller,其在视图层的render函数中实现的是总体的渲染,更底层的渲染则交给TodoView,在控制层的事件响应和事件监听实现的则也是封装度更高的处理。如添加一个todo,依次有如下的传递:

//View->Controller
"keypress #new-todo": "createOnEnter"

//Controller->Model
createOnEnter: function(e) {
   if (e.keyCode != 13) return;
   if (!this.input.val()) return;

   Todos.create({title: this.input.val()});
   this.input.val('');
}

//Model -> Controller
this.listenTo(Todos, 'add', this.addOne);

//Controller -> View
addOne: function(todo) {
   var view = new TodoView({model: todo});
   this.$("#todo-list").append(view.render().el);
}

在最后一个addOne函数中,则又包含了底层的MVC转换流程,但是这显然不是我们所关心的,它是由底层封装好的,在Backbone的框架会自动地进行MVC的逻辑传递。

Todo小结

这就是整个Todo Totuorial的结构。总的说来,BackBone所为我们提供的这种特定的结构很好地实现了MVC的架构,完成了View与Model的分离。而Controller则很好地充当了转换者的角色。

心得体会

由于之前没有学习过前端MVC的知识,因此在探究Todo实例的时候遇到了很多困难。Todo实例与传统的网页应用有很大的差异:

         a)  无静态html代码,为纯js实现

         b)  数据与界面的交互原理十分难懂

         c)  View的构建与数据的处理鸿沟太大。

         d)  事件监听与事件绑定用途不同,响应与回调流程容易混淆

一开始,真的很难理解Todo的结构,但是后来,反过来,从MVC的结构来思考,从视图开始分析,探究View->Controller->Model->Controller->View的线索。便得出了整体的结构以及Controller的传递过程。可以说,理解Controller这个桥梁对于贯通整个MVC结构有至关重要的作用。建议从View的输入下手,对Controller进行分析。

另一方面,可以适当采取自上而下与自下而上的结构进行分析。如对View的分析,采用自上而下方法较为容易入手,而Models采用自下而上的方法能帮助我们更清晰地理解Models的结构。

Javascript 相关文章推荐
javascript AOP 实现ajax回调函数使用比较方便
Nov 20 Javascript
30个让人兴奋的视差滚动(Parallax Scrolling)效果网站
Mar 04 Javascript
JQuery的$命名冲突详细解析
Dec 28 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
Feb 12 Javascript
使用jQuery.wechat构建微信WEB应用
Oct 09 Javascript
JavaScript模拟深蓝vs卡斯帕罗夫的国际象棋对局示例
Apr 22 Javascript
利用jquery实现实时更新歌词的方法
Jan 06 Javascript
JS数组操作之增删改查的简单实现
Aug 21 Javascript
基于JS实现web端录音与播放功能
Apr 17 Javascript
JS实现关闭小广告特效
Jan 29 Javascript
详解vue路由
Aug 05 Javascript
vue-cli打包后本地运行dist文件中的index.html操作
Aug 12 Javascript
backbone简介_动力节点Java学院整理
Jul 14 #Javascript
bootstrap基本配置_动力节点Java学院整理
Jul 14 #Javascript
easyui简介_动力节点Java学院整理
Jul 14 #Javascript
bootstrap是什么_动力节点Java学院整理
Jul 14 #Javascript
bootstrap精简教程_动力节点Java学院整理
Jul 14 #Javascript
简单实现js轮播图效果
Jul 14 #Javascript
JS获取填报扩展单元格控件的值的解决办法
Jul 14 #Javascript
You might like
PHP5中实现多态的两种方法实例分享
2014/04/21 PHP
php图片的二进制转换实现方法
2014/12/15 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
2019/02/15 PHP
游览器中javascript的执行过程(图文)
2012/05/20 Javascript
Javascript异步编程的4种方法让你写出更出色的程序
2013/01/17 Javascript
js中的json对象详细介绍
2014/10/29 Javascript
jQuery表格插件datatables用法汇总
2016/03/29 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
2016/05/20 Javascript
jsonp跨域请求实现示例
2017/03/13 Javascript
js学习总结之dom2级事件基础知识详解
2017/07/27 Javascript
javascript  删除select中的所有option的实例
2017/09/17 Javascript
iview通过Dropdown(下拉菜单)实现的右键菜单
2018/10/26 Javascript
js module大战
2019/04/19 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
TensorFlow损失函数专题详解
2018/04/26 Python
利用Python将每日一句定时推送至微信的实现方法
2018/08/13 Python
Python设计模式之模板方法模式实例详解
2019/01/17 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
2019/06/19 Python
详解python websocket获取实时数据的几种常见链接方式
2019/07/01 Python
django 环境变量配置过程详解
2019/08/06 Python
使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
2019/09/06 Python
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
Python中 Global和Nonlocal的用法详解
2020/01/20 Python
Tensorflow实现多GPU并行方式
2020/02/03 Python
tensorflow对图像进行拼接的例子
2020/02/05 Python
如何使用python记录室友的抖音在线时间
2020/06/29 Python
面向新手解析python Beautiful Soup基本用法
2020/07/11 Python
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
德国二手设计师时装和复古时装跳蚤市场:Mädchenflohmarkt
2020/11/09 全球购物
房务中心文员岗位职责
2014/04/16 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
聘用合同范本
2015/09/21 职场文书
详解Mysql和Oracle之间的误区
2021/05/18 MySQL
gateway与spring-boot-starter-web冲突问题的解决
2021/07/16 Java/Android
浅谈MySQL中的六种日志
2022/03/23 MySQL