Event handling between views

backbone-events, backbone-views, backbone.js

Solution

Not sure about the best practice but I found this solution trivial to implement. I created a global messaging object, bus, whatever:

window.App = {};
window.App.vent = _.extend({}, Backbone.Events);

You have to register the "triggerable" functions of PreviewView on the previously created event bus (according to your example, this should be in the `PreviewView`):

initialize: function () {
    App.vent.on('PreviewView.show', this.show, this);
}

Now you should be able to trigger any of registered events from anywhere within your application by calling: `App.vent.trigger`. For example when the user click on a row you will have something similar:

App.vent.trigger('PreviewView.show');

in case if you have to send and object along with the triggered event use:

App.vent.trigger('PreviewView.show', data);

Problem

Ok I have a layout like the one in this pic: The table in the upper part of the screen is made by: MessageListView ``` define(['backbone','collections/messages','views/message'], function(Backbone, MessageCollection, MessageView) { var MessageListView = Backbone.View.extend({ el: '#messagesContainer', initialize: function() { this.collection = new MessageCollection(); this.collection.fetch({reset:true}); this.listenTo( this.collection, 'reset', this.render ); this.table = this.$el.find("table tbody"); this.render(); }, render: function() { this.collection.each( function(message, index) { this.renderMessage(message, index); }, this); }, renderMessage: function(message, index) { var view = new MessageView({ model:message, className: (index % 2 == 0) ? "even" : "odd" }); this.table.append( view.render().el ); } }); return MessageListView; }); ``` MessageView ``` define(['backbone','models/message'], function(Backbone, MessageCollection, MessageView) { var MessageView = Backbone.View.extend({ template: _.template( $("#messageTemplate").html() ), render: function() { this.setElement( this.template(this.model.toJSON()) ); return this; }, events:{ 'click':'select' }, select: function() { // WHAT TO DO HERE? } }); return MessageView; }); ``` AppView ``` define(['backbone','views/messages'], function(Backbone, MessageList) { var App = Backbone.View.extend({ initialize: function() { new MessageList(); } }); return App; }); ``` I will soon add a new view (maybe "PreviewView") in the lower part of the screen. I want to make something happen inside the "PreviewView" when user clicks a row. For example, it could be interesting to display other model's attributes (details, e.g.) inside the PreviewView. What is the best practice? - holding a reference to PreviewView inside each MessageView ? - triggering events inside select method, and listening to them using on() inside the preview view. - using a transient "selected" attribute in my model, and make PreviewView listen to collection "change" events? Thank you, if you need more details tell me please, I'll edit the question.

Original source