Backbone View 之间通信的三种方式

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

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

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

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

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

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

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

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

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

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

1. 通过父视图传递事件

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

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 。把它注入到各个子视图中,用来广播事件。

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 对象可以直接调用,这样我就不必在每个子视图中手动注入它了。

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 对象,但是用起来却异常简洁。

(0)

相关推荐

  • 实例讲解JavaScript的Backbone.js框架中的View视图

    Backbone 中的 View 用来反映你 app 中 Model 的模样.它们会监听事件并作出相应的反应. 接下来的教程我不会告诉你如何把 Model 和 Collection 绑定到 View 上,而是主要讨论 View 是如何使用 javascript 模板库的,尤其是 Underscore.js's _.template. 这里我们使用 jQuery 来操作 DOM 元素,当然你也可以使用其他的库,例如 MooTools 或者 Sizzle,但是 Backbone 的官方文档推荐我们使

  • 简单了解Backbone.js的Model模型以及View视图的源码

    Backbone.Model 今天我们先来谈谈Backbone.js MVC 中的 M , Model是backbone的核心部分,包含着页面展示内容的数据,还有围绕着数据操作的各种 转换,校验,计算 ,权限控制,服务端交互等等操作,你可以通过 Backbone.Model.extend() 生成你的model , 当然生成的model也可以作为一个基类去向下扩展更多的model var People = Backbone.Model.extend({ }); var Man = People.

  • Backbone中View之间传值的学习心得

    Backbone中的View就是用来展示由Model层传出的数据,或者在View里产生的一些数据,包括输入框中输入等产生的数据,由当前View传递到另外一个View层里,应该怎么办呢,我之前读到一位博主<Backbone View的三种通信方式 >写的尤为的清晰,在我实际的项目中,常常使用的也就是最后一种方式. 嘿嘿,分享知识是一件快乐的事情,我就直接借鉴表述一下如下: 直接用 Backbone 作为事件注册机, 代码如下: var ApplicationView = Backbone.Vie

  • Backbone.js框架中简单的View视图编写学习笔记

    传统上用jQuery操作DOM,就类似C语言中的goto语句,随着项目复杂度增大,会越来越难以维护. 关于MVC(以及后续的MVP,MVVM),网上资源很多,就不展开.我们直接用代码来操练. index.html <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible

  • Backbone View 之间通信的三种方式

    在上篇文章给大家介绍了Backbone中View之间传值的学习心得.本文重点给大家介绍Backbone View 之间通信的三种方式. 掌握一个 MVC 框架,最关键的一节就是掌握如何在各个 View 之间通信.之前用 Angular 时,觉得基于事件的通信方式 ($on, $emit, $boardcast) 或者 基于 service 的方式都非常好用.转战 Backbone 之后,由于对 Backbone 的事件机制理解不够且使用非常灵活,一直没找到一个好的通信方式.直到看见这篇文章,作者

  • 详解Vue组件之间通信的七种方式

    使用Vue也有很长一段时间,但是一直以来都没对其组件之间的通信做一个总结,这次就借此总结一下. 父子组件之间的通信 1)props和$emit 父组件通过props将数据下发给props,子组件通过$emit来触发自定义事件来通知父组件进行相应的操作 具体代码如下: ``` // 父组件 <template> <div> <h3>props和$emit</h3> <Children v-on:changeMsg="changeMsg"

  • Android中Service与Activity之间通信的几种方式

    在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到Activity与Service之间的通信,我们一般在Activity中启动后台Service,通过Intent来启动,Intent中我们可以传递数据给Service,而当我们Service执行某些操作之后想要更新UI线程,我们应该怎么做呢?接下来我就介绍两种方式来实现Service与Activity之间的通信问题 1.通过Binder对象 当Activity通

  • 详解Android Service与Activity之间通信的几种方式

    在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到Activity与Service之间的通信,我们一般在Activity中启动后台Service,通过Intent来启动,Intent中我们可以传递数据给Service,而当我们Service执行某些操作之后想要更新UI线程,我们应该怎么做呢?接下来我就介绍两种方式来实现Service与Activity之间的通信问题 通过Binder对象 当Activity通过调

  • 详解vue组件通信的三种方式

    1. 第一种方式就是官方推荐的 官方推荐方式 有时候两个组件也需要通信(非父子关系).在简单的场景下,可以使用一个空的 Vue 实例作为中央事件总线. 本质是通过派发事件然后监听事件从而更改值,(父子组件通信也可用这个方式,但是不同的一点就是父子组件通信的时候可以不用一个空的Vue实例来做中转,这种方式我这里就不做演示的了,因为我的题目是非父子通信) 空的Vue实例 bus import Vue from 'vue' const bus = new Vue() export default bu

  • Android获取view高度的三种方式

    本文为大家分享了Android获取view高度的方法,供大家参考,具体内容如下 getMeasuredHeight()与getHeight的区别 实际上在当屏幕可以包裹内容的时候,他们的值相等, 只有当view超出屏幕后,才能看出他们的区别: getMeasuredHeight()是实际View的大小,与屏幕无关, 而getHeight的大小此时则是屏幕的大小. 当超出屏幕后,getMeasuredHeight()等于getHeight()加上屏幕之外没有显示的大小 具体方法 我们知道在oncr

  • vue中组件通信的八种方式(值得收藏!)

    前言 之前写了一篇关于vue面试总结的文章, 有不少网友提出组件之间通信方式还有很多, 这篇文章便是专门总结组件之间通信的 vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式, 就好像过年回家,坐着一屋子的陌生人,相互之间怎么称呼,这时就需要先知道自己和他们之间是什么样的关系. vue组件中关系说明: 如上图所示, A与B.A与C.B与D.C与E组件之间

  • springmvc url处理映射的三种方式集合

    目录 一.SpringMVC简介 二.工作流程与介绍 三.代码截图 以下组件通常使用框架提供实现: 1.DispatcherServlet:前端控制器 2.HandlerMapping:处理器映射器 3.Handler:处理器 4.HandlAdapter:处理器适配器 5. ViewResolver:视图解析器 6.View:视图 四.适配器作用 一.SpringMVC简介 SpringMVC是一种基于Spring实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,使用了MVC架构模

  • React组件间通信的三种方法(简单易用)

    目录 一.父子组件通信 二.跨级组件通信 1.逐层传值 2.跨级传值 三.兄弟(无嵌套)组件通信 四.路由传值 五.Redux React知识中一个主要内容便是组件之间的通信,以下列举几种常用的组件通信方式,结合实例,通俗易懂,建议收藏. 一.父子组件通信 原理:父组件通过props(与vue中的props区分开)向子组件通信,子组件通过回调事件与父组件通信. 首先,先创建一个父组件Parent.js跟子组件Children.js,二者的关系为直接父子关系. Parent.js父组件如下,给父组

  • C# 三种方式实现Socket数据接收

    目录 Stream.Read 方法 将数据接收放到 while (true) Stream.Read 方法 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数. 语法: public abstract int Read(byte[] buffer, int offset, int count) 参数: buffer : 字节数组.此方法返回时,该缓冲区包含指定的字符数组,该数组的  offset 和 ( offset +  count -1) 之间的值由从当前源中读取的字

随机推荐