2012-02-22 50 views
19

我有,看起來像下面這樣的視圖結構的骨幹應用程序 - 注意,我已經刪除的實現,模型,集合等爲簡潔:如何在Backbone View層次結構中「冒泡」事件?

NewsListView = Backbone.View.extend({ 

    el: $('li#newspane'), 

    // This is what I would like to be able to do 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
    }, 

    render: function() { 
    }, 

    reset: function(){ 
    } 

}); 

FilterView = Backbone.View.extend({ 

    el: $('li.filter'), 

    initialize: function() { 
    }, 

    render: function() { 
    }, 

    toggleFilter: function() { 
    } 

}); 

AllView = Backbone.View.extend({ 

    initialize: function() { 

     this.newsListView = new NewsListView(); 
     this.filterView = new FilterView(); 

    } 

}); 

從本質上講,只要FilterViewtoggleFilter()功能被稱爲,我想發起一個叫做filtered的事件或類似的事件,然後被NewsListView抓到,然後它調用它的reset()函數。如果沒有將NewsListView對象的參考傳遞給我的FilterView,我不確定如何將其發送給它。有任何想法嗎?

回答

0

所以,我想出了一個解決方案 - 創建一個對象,擴展Backbone.Events,並將其作爲參數傳遞給多個視圖。這幾乎就像是演員之間的消息傳遞,或者什麼。無論如何 - 我發佈這個作爲一個答案,以防其他人需要快速解決方案,但我不會接受答案。這感覺哈克。我仍然希望看到更好的解決方案。

NewsListView = Backbone.View.extend({ 
    el: $('li#newspane'), 

    // Too bad this doesn't work, it'd be really convenient 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
     // but at least this does 
     this.options.eventProxy.bind('filtered', this.reset); 
    }, 
    render: function() {}, 
    reset: function() {} 
}); 

FilterView = Backbone.View.extend({ 
    el: $('li.filter'), 

    initialize: function() {}, 
    render: function() {}, 
    toggleFilter: function() { 
     this.options.eventProxy.trigger('filtered'); 
    } 
}); 

AllView = Backbone.View.extend({ 
    initialize: function() { 
     var eventProxy = {}; 
     _.extend(eventProxy, Backbone.Events); 
     this.newsListView = new NewsListView({eventProxy: eventProxy}); 
     this.filterView = new FilterView({eventProxy: eventProxy}); 
    } 
}); 
0

這個問題可以通過使用small backbone.js破解來解決。只需修改Backbone.Events.trigger傳遞事件到this.parent

if this.parent != null 
3

你可能會能夠使用jQuery事件和骨幹事件屬性的已有功能來完成此操作。

例如,而不是從你的子視圖裏面做這樣的:這是一個父母,祖父母,等你的孩子視圖的任何視圖

this.$el.trigger("yourevent", this); 

然後:

this.trigger("yourevent", this); 

做到這一點,而不是,通過在該視圖的事件對象上定義屬性來收聽該視圖的$ el上的事件:

events:{ 
    "yourevent":"yourhandler" 
} 

並定義該視圖處理程序以及:

yourhandler:function(subview) { 
} 

於是就這樣,一個視圖並不需要了解存在哪些後裔的觀點,唯一事件是有意的類型,如果視圖始發事件被破壞,祖先觀點沒有什麼需要改變。如果祖先視圖被破壞,骨幹將自動分離處理程序。

警告:我還沒有真正嘗試過這一點,所以在那裏可能有一個問題。

+0

這不適合我。 – anyaelise 2015-11-17 17:00:14

+0

謝謝你的aha!時刻。 – 2016-02-24 23:29:32

0

我發現觸發和監聽事件的最簡單方法就是使用Backbone對象本身。它已經在它混合功能的事件,所以你可以觸發如:

Backbone.trigger('view:eventname',{extra_thing:whatever, thing2:whatever2}); 

然後,在您的應用程序任何其他骨幹視圖,您可以偵聽此事件如:

Backbone.on('view:eventname', function(passed_obj) { 
    console.log(passed_obj.extra_thing); 
}); 

我不確定在不使用Backbone對象作爲您的事件處理程序的優點,而是創建一個單獨的對象來執行它,但對於快速和骯髒的工作,上述工作正常。 HTH!

注意:一個缺點是每個聽衆都會「聽到」以這種方式觸發的每一個事件。不知道這個大O是什麼,但工作要小心,不要用很多這種東西來超載你的觀點。再次:這是快速和骯髒的! :)