Backbone View 之間通信的三種方式
在上篇文章給大家介紹了Backbone中View之間傳值的學(xué)習(xí)心得。本文重點(diǎn)給大家介紹Backbone View 之間通信的三種方式。
掌握一個(gè) MVC 框架,最關(guān)鍵的一節(jié)就是掌握如何在各個(gè) View 之間通信。之前用 Angular 時(shí),覺得基于事件的通信方式 ($on, $emit, $boardcast) 或者 基于 service 的方式都非常好用。轉(zhuǎn)戰(zhàn) Backbone 之后,由于對(duì) Backbone 的事件機(jī)制理解不夠且使用非常靈活,一直沒找到一個(gè)好的通信方式。直到看見這篇文章,作者通過一個(gè)簡單的例子,層層深入,把 Backbone View 之間通信的三種方式講的清晰明了。譯文如下:
我正在開發(fā)的這個(gè)網(wǎng)頁主要有兩部分,分別是 document 和 sidebar。
如上圖所示,我設(shè)立了三個(gè)視圖 (view) :
ApplicationView - 作為最外層視圖來包含下級(jí)視圖
DocumentView - 展示正在編輯或?yàn)g覽的內(nèi)容
SidebarView - 展示一些和 document 相關(guān)的信息
DocumentView 和 SidebarView 作為 ApplicationView 的子視圖,所以整體的視圖結(jié)構(gòu)如下圖所示:
用戶在任意一個(gè)子視圖進(jìn)行操作,另一個(gè)子視圖都需要隨之變化。但由于兩個(gè)子視圖之間并不能直接通知對(duì)方(也就是說,它們的作用域沒有直接聯(lián)系,不像父視圖,可以包含它所有子視圖的作用域),所以,我需要一個(gè)事件機(jī)制。
在我谷歌和參考其他人的方法之后,我總結(jié)出了如下三種不同的通信方式。
1. 通過父視圖傳遞事件
我通過父視圖 ( ApplicationView ) 來為它的兩個(gè)子視圖傳遞事件。因?yàn)楦敢晥D包含它所有子視圖的作用域,因此用它作為事件傳遞的媒介最好不過。
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. } });
但是,這種方法并不高效。因?yàn)槲倚枰?ApplicationView 中添加一個(gè)額外的事件處理函數(shù) documentEdited() 。如果子視圖有一堆事件傳過來,則在父視圖中會(huì)不斷觸發(fā)事件處理函數(shù),導(dǎo)致它不堪重負(fù)。
那么來看看第二種方法。
2. 通過 EventBus 在視圖間通信
我通過繼承 Backbone.Events 來創(chuàng)建一個(gè)全局對(duì)象 EventBus 。把它注入到各個(gè)子視圖中,用來廣播事件。
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. } });
在這個(gè)方法中,我把 EventBus 作為一個(gè)全局對(duì)象用來注冊(cè)事件。如果我想在各個(gè)視圖之間通信,只需要在視圖中注入 EventBus ,就可以通過它方便地觸發(fā)或監(jiān)聽事件了。
注意:如果你不想要?jiǎng)?chuàng)建全局對(duì)象,你仍然可以創(chuàng)建模塊 (module) 或視圖 (view) 級(jí)別的 EventBus 用來通信。
這個(gè)方法已經(jīng)明顯優(yōu)于第一種方法了。但是需要我們手動(dòng)的在子視圖中引入 EventBus ,說明還有可以改進(jìn)的空間,那么,來看看第三種方法。
3. 直接用 Backbone 作為事件注冊(cè)機(jī)
在第二種方法中,我創(chuàng)建了一個(gè)單獨(dú)的 EventBus ,繼承自 Backbone.Events 。但最近我悟到 Backbone 對(duì)象本身就是一個(gè)混合了 Events 的對(duì)象,所以我直接用 Backbone 廣播事件,就無需單另創(chuàng)建的 EventBus 了。
而且 Backbone 對(duì)象可以直接調(diào)用,這樣我就不必在每個(gè)子視圖中手動(dòng)注入它了。
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. } });
總結(jié)
我最終在我的項(xiàng)目中使用了第三種方法。而且在我看來,雖然它直接依賴了全局的 Backbone 對(duì)象,但是用起來卻異常簡潔。
相關(guān)文章
backbone簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了backbone簡介,詳細(xì)的介紹了backbone簡介和用法,有興趣的可以了解一下2017-07-07詳解Backbone.js框架中的模型Model與其集合collection
這篇文章主要介紹了Backbone.js框架中的模型Model與其集合collection,Backbone擁有與傳統(tǒng)MVC框架相類似的Model與View結(jié)構(gòu),需要的朋友可以參考下2016-05-05BackBone及其實(shí)例探究_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了BackBone及其實(shí)例探究,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07講解JavaScript的Backbone.js框架的MVC結(jié)構(gòu)設(shè)計(jì)理念
這篇文章主要介紹了JavaScript的Backbone.js框架的MVC結(jié)構(gòu)設(shè)計(jì)理念,相比較于Angular.js,同樣為MVC結(jié)構(gòu)的Backbone則顯得輕巧許多,需要的朋友可以參考下2016-02-02Backbone.js框架中簡單的View視圖編寫學(xué)習(xí)筆記
這篇文章主要介紹了Backbone.js框架中簡單的View編寫學(xué)習(xí)筆記,Backbone是JavaScript的一款高人氣MVC框架,需要的朋友可以參考下2016-02-02JavaScript的Backbone.js框架的一些使用建議整理
這篇文章主要介紹了JavaScript的Backbone.js框架的一些使用建議整理,文中列的幾點(diǎn)主要還是針對(duì)DOM方面的操作,需要的朋友可以參考下2016-02-02關(guān)于backbone url請(qǐng)求中參數(shù)帶有中文存入數(shù)據(jù)庫是亂碼的快速解決辦法
這篇文章主要介紹了關(guān)于backbone url請(qǐng)求中參數(shù)帶有中文存入數(shù)據(jù)庫是亂碼的快速解決辦法的相關(guān)資料,需要的朋友可以參考下2016-06-06全面解析JavaScript的Backbone.js框架中的Router路由
這篇文章主要介紹了Backbone.js框架中的Router路由功能,Router在Backbone中相當(dāng)于一個(gè)MVC框架中的Controller控制器功能,需要的朋友可以參考下2016-05-05