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 相关文章推荐
网页设计常用的一些技巧
Dec 22 Javascript
JavaScript 反科里化 this [译]
Sep 20 Javascript
cument.execCommand()用法深入理解
Dec 04 Javascript
js中的for如何实现foreach中的遍历
May 31 Javascript
Egret引擎开发指南之运行项目
Sep 03 Javascript
简单学习vue指令directive
Nov 03 Javascript
BootStrap中
Dec 10 Javascript
Vue filters过滤器的使用方法
Jul 14 Javascript
JavaScript全屏和退出全屏事件总结(附代码)
Aug 17 Javascript
Vue中render方法的使用详解
Jan 26 Javascript
解决js相同的正则多次调用test()返回的值却不同的问题
Oct 10 Javascript
vue 中Virtual Dom被创建的方法
Apr 15 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
SONY ICF-SW7600的电路分析
2021/03/02 无线电
解析PHP多种序列化与反序列化的方法
2013/06/06 PHP
PHP中串行化用法示例
2016/11/16 PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
2018/06/20 PHP
javascript实现的在当前窗口中漂浮框的代码
2010/03/15 Javascript
js以对象为索引的关联数组
2010/07/04 Javascript
jQuery学习笔记 更改jQuery对象
2012/09/19 Javascript
a标签的href和onclick 的事件的区别介绍
2013/07/26 Javascript
JS防止用户多次提交的简单代码
2013/08/01 Javascript
jquery.post用法关于type设置问题补充
2014/01/03 Javascript
jQuery操作JSON的CRUD用法实例
2015/02/25 Javascript
javascript中alert()与console.log()的区别
2015/08/26 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
2016/05/11 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
详解React中setState回调函数
2018/06/14 Javascript
JavaScript中的垃圾回收与内存泄漏示例详解
2019/05/02 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
2020/11/03 Javascript
[00:37]DOTA2上海特级锦标赛 OG战队宣传片
2016/03/03 DOTA
python在非root权限下的安装方法
2018/01/23 Python
python psutil模块使用方法解析
2019/08/01 Python
python 批量修改 labelImg 生成的xml文件的方法
2019/09/09 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
Python 如何定义匿名或内联函数
2020/08/01 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
Canvas获取视频第一帧缩略图的实现
2020/11/11 HTML / CSS
创建索引时需要注意的事项
2013/05/13 面试题
公司周年庆活动方案
2014/08/25 职场文书
农民工预备党员思想汇报
2014/09/14 职场文书
2014年招商引资工作总结
2014/11/22 职场文书
2014年帮扶工作总结
2014/11/26 职场文书
博士给导师的自荐信
2015/03/06 职场文书
2015教师个人年度工作总结
2015/10/23 职场文书
Eclipse+Java+Swing+Mysql实现电影购票系统(详细代码)
2022/01/18 Java/Android
python+pytest接口自动化之token关联登录的实现
2022/04/06 Python