Backbone View 之间通信的三种方式


Posted in Javascript onAugust 09, 2016

在上篇文章给大家介绍了Backbone中View之间传值的学习心得。本文重点给大家介绍Backbone View 之间通信的三种方式。

掌握一个 MVC 框架,最关键的一节就是掌握如何在各个 View 之间通信。之前用 Angular 时,觉得基于事件的通信方式 ($on, $emit, $boardcast) 或者 基于 service 的方式都非常好用。转战 Backbone 之后,由于对 Backbone 的事件机制理解不够且使用非常灵活,一直没找到一个好的通信方式。直到看见这篇文章,作者通过一个简单的例子,层层深入,把 Backbone View 之间通信的三种方式讲的清晰明了。译文如下:

我正在开发的这个网页主要有两部分,分别是 document 和 sidebar。

Backbone View 之间通信的三种方式 

如上图所示,我设立了三个视图 (view) :

Backbone View 之间通信的三种方式 

ApplicationView - 作为最外层视图来包含下级视图

DocumentView - 展示正在编辑或浏览的内容

SidebarView - 展示一些和 document 相关的信息

DocumentView 和 SidebarView 作为 ApplicationView 的子视图,所以整体的视图结构如下图所示:

用户在任意一个子视图进行操作,另一个子视图都需要随之变化。但由于两个子视图之间并不能直接通知对方(也就是说,它们的作用域没有直接联系,不像父视图,可以包含它所有子视图的作用域),所以,我需要一个事件机制。

在我谷歌和参考其他人的方法之后,我总结出了如下三种不同的通信方式。

1. 通过父视图传递事件

我通过父视图 ( ApplicationView ) 来为它的两个子视图传递事件。因为父视图包含它所有子视图的作用域,因此用它作为事件传递的媒介最好不过。

Backbone View 之间通信的三种方式 

JavaScript 代码如下:

var ApplicationView = Backbone.View.extend({
initialize : function(){
this.documentView = new DocumentView({parent:this});
this.sidebarView = new SidebarView({parent:this});
this.documentView.on('edit', this.documentEdited, this);
},
documentEdited : function(){
// do some stuff
this.sidebarView.trigger('documentEdit');
}
});
var DocumentView = Backbone.View.extend({
onEdit : function(){
this.trigger('edit');
}
});
var SidebarView = Backbone.View.extend({
initialize : function(){
this.on('documentEdit', this.onDocumentEdit, this);
},
onDocumentEdit : function(){
// react to document edit.
}
});

但是,这种方法并不高效。因为我需要在 ApplicationView 中添加一个额外的事件处理函数 documentEdited() 。如果子视图有一堆事件传过来,则在父视图中会不断触发事件处理函数,导致它不堪重负。

那么来看看第二种方法。

2. 通过 EventBus 在视图间通信

我通过继承 Backbone.Events 来创建一个全局对象 EventBus 。把它注入到各个子视图中,用来广播事件。

Backbone View 之间通信的三种方式 

JavaScript 代码如下:

var ApplicationView = Backbone.View.extend({
initialize : function(){
this.eventBus = _.extend({}, Backbone.Events);
this.documentView = new DocumentView({
eventBus : this.eventBus
});
this.sidebarView = new SidebarView({
eventBus : this.eventBus
});
},
});
var DocumentView = Backbone.View.extend({
initialize : function(options){
this.eventBus = options.eventBus;
},
onEdit : function(){
this.eventBus.trigger('documentEdit');
}
});
var SidebarView = Backbone.View.extend({
initialize : function(options){
this.eventBus = options.eventBus;
this.eventBus.on('documentEdit', this.onDocumentEdit, this);
},
onDocumentEdit : function(){
// react to document edit.
}
});

在这个方法中,我把 EventBus 作为一个全局对象用来注册事件。如果我想在各个视图之间通信,只需要在视图中注入 EventBus ,就可以通过它方便地触发或监听事件了。

注意:如果你不想要创建全局对象,你仍然可以创建模块 (module) 或视图 (view) 级别的 EventBus 用来通信。

这个方法已经明显优于第一种方法了。但是需要我们手动的在子视图中引入 EventBus ,说明还有可以改进的空间,那么,来看看第三种方法。

3. 直接用 Backbone 作为事件注册机

在第二种方法中,我创建了一个单独的 EventBus ,继承自 Backbone.Events 。但最近我悟到 Backbone 对象本身就是一个混合了 Events 的对象,所以我直接用 Backbone 广播事件,就无需单另创建的 EventBus 了。

而且 Backbone 对象可以直接调用,这样我就不必在每个子视图中手动注入它了。

Backbone View 之间通信的三种方式 

JavaScript 代码如下:

var ApplicationView = Backbone.View.extend({
initialize : function(){
this.documentView = new DocumentView();
this.sidebarView = new SidebarView();
},
});
var DocumentView = Backbone.View.extend({
onEdit : function(){
Backbone.trigger('documentEdit');
}
});
var SidebarView = Backbone.View.extend({
initialize : function(options){
Backbone.on('documentEdit', this.onDocumentEdit, this);
},
onDocumentEdit : function(){
// react to document edit.
}
});

总结

我最终在我的项目中使用了第三种方法。而且在我看来,虽然它直接依赖了全局的 Backbone 对象,但是用起来却异常简洁。

Javascript 相关文章推荐
js中cookie的使用详细分析
May 28 Javascript
使用Firebug对js进行断点调试的图文方法
Apr 02 Javascript
JavaScript 继承使用分析
May 12 Javascript
Struts2的s:radio标签使用及用jquery添加change事件
Apr 08 Javascript
深入理解JQuery keyUp和keyDown的区别
Dec 12 Javascript
jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
Oct 10 Javascript
全面解析Bootstrap手风琴效果
Apr 17 Javascript
JavaScript自学笔记(必看篇)
Jun 23 Javascript
bootstrap中模态框、模态框的属性实例详解
Feb 17 Javascript
vue+iview动态渲染表格详解
Mar 19 Javascript
axios封装,使用拦截器统一处理接口,超详细的教程(推荐)
May 02 Javascript
jquery实现两个div中的元素相互拖动的方法分析
Apr 05 jQuery
Backbone中View之间传值的学习心得
Aug 09 #Javascript
全面了解函数声明与函数表达式、变量提升
Aug 09 #Javascript
jQuery 生成svg矢量二维码
Aug 09 #Javascript
浅谈JavaScript中变量和函数声明的提升
Aug 09 #Javascript
浅谈js基本数据类型和typeof
Aug 09 #Javascript
js中判断变量类型函数typeof的用法总结
Aug 09 #Javascript
详解js实现线段交点的三种算法
Aug 09 #Javascript
You might like
初次接触php抽象工厂模式(Elgg)
2010/03/21 PHP
php中base_convert()进制数字转换函数实例
2014/11/20 PHP
PHP Try-catch 语句使用技巧
2016/02/28 PHP
Laravel 验证码认证学习记录小结
2019/12/20 PHP
PHP Pipeline 实现中间件的示例代码
2020/04/26 PHP
面向对象Javascript核心支持代码分享
2012/05/23 Javascript
基于jquery的滚动条滚动固定div(附演示下载)
2012/10/29 Javascript
jQuery获取CSS样式中的颜色值的问题,不同浏览器格式不同的解决办法
2013/05/13 Javascript
利用js实现遮罩以及弹出可移动登录窗口
2013/07/08 Javascript
js实现点击图片改变页面背景图的方法
2015/02/28 Javascript
jQuery EasyUI提交表单验证
2016/07/19 Javascript
如何用JS/HTML将时间戳转换为“xx天前”的形式
2017/02/06 Javascript
用JavaScript和jQuery实现瀑布流
2017/03/19 Javascript
微信小程序微信支付接入开发实例详解
2017/04/12 Javascript
详解Vue 动态添加模板的几种方法
2017/04/25 Javascript
微信小程序 自定义Toast实例代码
2017/06/12 Javascript
Vue自定义指令使用方法详解
2017/08/21 Javascript
vue中使用iview自定义验证关键词输入框问题及解决方法
2018/03/26 Javascript
JavaScript 浏览器对象模型BOM原理与常见用法实例分析
2019/12/16 Javascript
Javascript call及apply应用场景及实例
2020/08/26 Javascript
举例详解Python中的split()函数的使用方法
2015/04/07 Python
Python使用django搭建web开发环境
2017/06/09 Python
Python中的支持向量机SVM的使用(附实例代码)
2019/06/26 Python
Anaconda的安装与虚拟环境建立
2020/11/18 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
借助HTML5 Canvas来绘制三角形和矩形等多边形的方法
2016/03/14 HTML / CSS
html5的pushstate以及监听浏览器返回事件的实现
2020/08/11 HTML / CSS
旅游管理实习自我鉴定
2013/09/29 职场文书
环境工程专业个人求职信
2013/12/05 职场文书
房地产营销策划方案
2014/02/08 职场文书
医院信息公开实施方案
2014/05/09 职场文书
计生专干事迹
2014/05/28 职场文书
市级三好学生评语
2014/12/29 职场文书
Win11 BitLocker 驱动器加密
2022/04/19 数码科技
vue如何在data中引入图片的正确路径
2022/06/05 Vue.js
uniapp开发打包多端应用完整方法指南
2022/12/24 Javascript