如上图所示,我设立了三个视图 (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 stuffthis.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() 。如果子视图有一堆事件传过来,则在父视图中会不断触发事件处理函数,导致它不堪重负。
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 ,就可以通过它方便地触发或监听事件了。
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.}});总结