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 相关文章推荐
JavaScript CSS修改学习第一章 查找位置
Feb 19 Javascript
跨浏览器开发经验总结(四) 怎么写入剪贴板
May 13 Javascript
js简单实现交换Li的值
May 22 Javascript
Node.js的特点和应用场景介绍
Nov 04 Javascript
超详细的javascript数组方法汇总
Nov 21 Javascript
跟我学习javascript的垃圾回收机制与内存管理
Nov 23 Javascript
window.open不被拦截的简单实现代码(推荐)
Aug 04 Javascript
VC调用javascript的几种方法(推荐)
Aug 09 Javascript
js实现图片懒加载效果
Jul 17 Javascript
vue单页应用中如何使用jquery的方法示例
Jul 27 jQuery
浅谈vue3中effect与computed的亲密关系
Oct 10 Javascript
vue将data恢复到初始状态 && 重新渲染组件实例
Sep 04 Javascript
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
destoon常用的安全设置概述
2014/06/21 PHP
php分割合并两个字符串的函数实例
2015/06/19 PHP
解决php的“It is not safe to rely on the system’s timezone settings”问题
2015/10/08 PHP
php中使用websocket详解
2016/09/23 PHP
php-beanstalkd消息队列类实例分享
2017/07/19 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
Prototype 工具函数 学习
2009/07/23 Javascript
捕获浏览器关闭、刷新事件不同情况下的处理方法
2013/06/02 Javascript
jquery二级导航内容均分的原理及实现
2013/08/13 Javascript
浅析JavaScript中的常用算法与函数
2013/11/21 Javascript
JS中的构造函数详细解析
2014/03/10 Javascript
BootStrap的alert提示框的关闭后再显示怎么解决
2016/05/17 Javascript
JavaScript代码实现图片循环滚动效果
2020/03/19 Javascript
AngularJS HTML DOM详解及示例代码
2016/08/17 Javascript
AngularJS表单和输入验证实例
2016/11/02 Javascript
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
Angular项目如何升级至Angular6步骤全纪录
2018/09/03 Javascript
Vue使用虚拟dom进行渲染view的方法
2019/12/26 Javascript
Python 高级专用类方法的实例详解
2017/09/11 Python
python通过tcp发送xml报文的方法
2018/12/28 Python
使用python PIL库实现简单验证码的去噪方法步骤
2019/05/10 Python
python 生成器和迭代器的原理解析
2019/10/12 Python
详解centos7+django+python3+mysql+阿里云部署项目全流程
2019/11/15 Python
Win10环境中如何实现python2和python3并存
2020/07/20 Python
10张动图学会python循环与递归问题
2021/02/06 Python
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
美国床垫和床上用品公司:Nest Bedding
2017/06/12 全球购物
在C语言中实现抽象数据类型什么方法最好
2014/06/26 面试题
个人能力自我鉴赏
2014/01/25 职场文书
坚定理想信念心得体会
2014/03/11 职场文书
绩效考核实施方案
2014/03/18 职场文书
理想点亮人生演讲稿
2014/05/21 职场文书
千与千寻观后感
2015/06/04 职场文书
走近毛泽东观后感
2015/06/04 职场文书
钢铁是怎样炼成的读书笔记
2015/06/29 职场文书
筑梦中国心得体会
2016/01/18 职场文书