BackBone及其实例探究
摘要
我们小组对MVC框架进行了学习。我的队友们已经在博客中对MVC的设计模式及优缺点进行了详细的探讨与分析,因此我的博客中只对MVC进行简单的介绍,而我将把重心放在Backbone MVC框架一些重点的阐述,并通过对一个实例较为详细的分析来探究如何利用Backbone框架来实现MVC结构。
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。
具体应用请见:http://localtodos.com/
应用源代码请见:http://backbonejs.org/docs/todos.html
代码中设计了四个“类”来实现任务单的功能:
//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的结构。
结语
前端MVC是一个大的课题,今后还需要在实践中多学习,多体会,培养自己的MVC思维,使自己拥有更好的架构能力。加油!
By Jianglinnan
We are fruits
BackBone及其实例探究的更多相关文章
- DeepLearning.ai学习笔记(四)卷积神经网络 -- week2深度卷积神经网络 实例探究
一.为什么要进行实例探究? 通过他人的实例可以更好的理解如何构建卷积神经网络,本周课程主要会介绍如下网络 LeNet-5 AlexNet VGG ResNet (有152层) Inception 二. ...
- ng-深度学习-课程笔记-12: 深度卷积网络的实例探究(Week2)
1 实例探究( Cast Study ) 这一周,ng对几个关于计算机视觉的经典网络进行实例分析,LeNet-5,AlexNet,VGG,ResNet,Inception. 2 经典网络( Class ...
- 实例探究Aspectj,解析SentinelResourceAspect
为了学习SentinelResourceAspect,这篇文章里我用Aspectj实现一个AOP实例,一起来看下. Sentinel 提供了 @SentinelResource 注解用于定义资源,支持 ...
- 【iOS发展-53】实例探究:scrollView使用方法和解决方案无法滚动核心
案例效果: (1)基本的就是练习scrollView的使用方法.界面里面的其它元素基本都是UIView和UIButton堆砌起来的. (2)主要用代码实现.当然,能够先用storyboard拖个scr ...
- Halcon二维仿射变换实例探究
二维仿射变换,顾名思义就是在二维平面内,对对象进行平移.旋转.缩放等变换的行为(当然还有其他的变换,这里仅论述这三种最常见的). Halcon中进行仿射变换的常见步骤如下: ① 通过hom_mat2d ...
- Backbone中的model和collection在做save或者create操作时, 如何选择用POST还是PUT方法 ?
Model和Collection和后台的WEB server进行数据同步非常方便, 都只需要在实行里面添加一url就可以了,backbone会在model进行save或者collection进行cre ...
- 【转】Backbone使用总结
转自 http://www.pchou.info/javascript/2014/06/26/backbone-summary-01.html 开始在项目中大规模使用backbone,一路磕磕碰碰, ...
- Backbone笔记(续)
Backbone Bockbone 总览 Backbone 与 MVC 模式:解决某一类问题的通用方案 - 套路 MVC:一种架构模式,解耦代码,分离关注点 M(Model) - 数据模型 V(Vie ...
- 如何对Backbone.Collection进行过滤操作
首先我想说的是这篇文章的题目起的很怪,因为我不知道起个什么名字比较好.渲染列表是我们应用中最常见的操作了吧,在运用Backbone的应用中,我们一般会把列表作为一个Collcetion,然后指定一个V ...
随机推荐
- 使用C#删除一个字符串数组中的空字符串
C#中要如何才能删除一个字符串数组中的空字符串呢?随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化.以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和过滤.C#3. ...
- MyBatis 中的级联
MyBatis 的级联分为 3 种. 1.鉴别器(discriminator):它是根据某些条件决定采用具体实现类级联的方案,比如体检表要根据性别去区分. 2.一对一(association):比如学 ...
- 网络唤醒(WOL)全解指南:原理篇
什么是网络唤醒 网络唤醒(Wake-on-LAN,WOL)是一种计算机局域网唤醒技术,使局域网内处于关机或休眠状态的计算机,将状态转换成引导(Boot Loader)或运行状态.无线唤醒(Wake-o ...
- 微信支付的notify.php中如何获取订单号(php版)
不要直接使用demo中的notify.php,重写notify.php,继承WxPayNotify(可参考微信api),具体如下: require_once "WxPay.Api.php&q ...
- Android 使用第三方登录(QQ和新浪微博)
账号申请什么的我就在这里略过了!(相信大家看看文档都能够处理的)本篇博客仅作引导用--主要提供给哪些不知道怎样入手的朋友.(如果需要更加强大的功能大家可以看一下开放平台上的文档,上面都有的) 使用QQ ...
- Android调用系统的打电话和发短信界面(1.将消息内容带过去2.实现群发)
package com.example.myapi.sms; import android.app.Activity; import android.content.Intent; import an ...
- 微信小程序开发 [06] 一些补充的知识点
0.写在前面的话 前几章的内容串联起来,基本上已经能写比较基础的小程序页面逻辑了,当然,wxml和wxss的我并没有写,因为前端我也并不擅长.这个章节,准备随便叨叨,然后补充一些之前没有提到的基础知识 ...
- 2017-2018-2 20155224『网络对抗技术』Exp4:恶意代码分析
原理与实践说明 实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systr ...
- 《图说VR入门》——DeepoonVR的大鹏(陀螺仪)枪
<图说VR入门>--VR大朋的(陀螺仪)枪 本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接: http://blog.csdn.net/cartzhang/ar ...
- mfc CAnimateCtrl
知识点: CAnimateCtrl成员函数 播放avi动画 一. CAnimateCtrl成员函数 Autoplay; CAnimateCtrl ::成员函数 Open 打开avi视频 Play 播放 ...