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 相关文章推荐
jQuery快速上手:写jQuery与直接写JS的区别详细解析
Aug 26 Javascript
使用javascript获取页面名称
Dec 23 Javascript
JavaScript显示表单内元素数量的方法
Apr 02 Javascript
JavaScript高级教程5.6之基本包装类型(详细)
Nov 23 Javascript
基于jquery编写的放大镜插件
Mar 23 Javascript
Angular 2应用的8个主要构造块有哪些
Oct 17 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
Oct 31 Javascript
jQuery Easy UI中根据第一个下拉框选中的值设置第二个下拉框是否可以编辑
Nov 29 Javascript
微信小程序 九宫格实例代码
Jan 21 Javascript
微信小程序封装自定义弹窗的实现代码
May 08 Javascript
vue实现百度搜索功能
Dec 28 Javascript
vue中三级导航的菜单权限控制
Mar 31 Vue.js
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模块 Memcached功能多于Memcache
2011/06/14 PHP
php简单smarty入门程序实例
2015/06/11 PHP
thinkPHP中create方法与令牌验证实例浅析
2015/12/08 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
php设计模式之装饰模式应用案例详解
2019/06/17 PHP
javascript HTMLEncode HTMLDecode的完整实例(兼容ie和火狐)
2009/06/02 Javascript
JS简单实现文件上传实例代码(无需插件)
2013/11/15 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
2014/06/15 Javascript
javascript实现字符串反转的方法
2015/02/05 Javascript
JavaScript验证Email(3种方法)
2015/09/21 Javascript
NodeJs——入门必看攻略
2016/06/27 NodeJs
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
AngularJS实现页面定时刷新
2017/03/14 Javascript
微信小程序 图片上传实例详解
2017/05/05 Javascript
js通过Date对象实现倒计时动画效果
2017/10/27 Javascript
vue实现商城上货组件简易版
2017/11/27 Javascript
javascript实现日历效果
2019/06/17 Javascript
python插入数据到列表的方法
2015/04/30 Python
python用10行代码实现对黄色图片的检测功能
2015/08/10 Python
Python实现将doc转化pdf格式文档的方法
2018/01/19 Python
python验证码识别教程之灰度处理、二值化、降噪与tesserocr识别
2018/06/04 Python
python实现合并多个list及合并多个django QuerySet的方法示例
2019/06/11 Python
Python任意字符串转16, 32, 64进制的方法
2019/06/12 Python
使用Python操作ArangoDB的方法步骤
2020/02/02 Python
Python argparse模块使用方法解析
2020/02/20 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
怎样让char类型的东西转换成int类型
2013/12/09 面试题
文明美德伴我成长演讲稿
2014/05/12 职场文书
2014年党员加强作风建设思想汇报
2014/09/15 职场文书
2014班子“三严三实”对照检查材料思想汇报
2014/09/18 职场文书
教师节横幅标语
2014/10/08 职场文书
求职自荐信怎么写
2015/03/04 职场文书
2015中学学校工作总结
2015/07/20 职场文书
创业开店,这样方式更合理
2019/08/26 职场文书
详解Html5项目适配系统深色模式方案总结
2021/04/14 HTML / CSS
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android