Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js - how to communicate between views?

I have a single page web app with multiple backbone.js views. The views must sometimes communicate with each other. Two examples:

  1. When there are two ways views presenting a collection in different ways simultaneously and a click on an item in one view must be relayed to the other view.
  2. When a user transitions to the next stage of the process and the first view passes data to the second.

To decouple the views as much as possible I currently use custom events to pass the data ($(document).trigger('customEvent', data)). Is there a better way to do this?

like image 494
Johnny Avatar asked Jul 23 '12 09:07

Johnny


2 Answers

One widely used technique is extending the Backbone.Events -object to create your personal global events aggregator.

var vent = {}; // or App.vent depending how you want to do this
_.extend(vent, Backbone.Events);

Depending if you're using requirejs or something else, you might want to separate this into its own module or make it an attribute of your Application object. Now you can trigger and listen to events anywhere in your app.

// View1
vent.trigger('some_event', data1, data2, data3, ...);

// View2
vent.on('some_event', this.reaction_to_some_event);

This also allows you to use the event aggregator to communicate between models, collections, the router etc. Here is Martin Fowler's concept for the event aggregator (not in javascript). And here is a more backboney implementation and reflection on the subject more in the vein of Backbone.Marionette, but most of it is applicable to vanilla Backbone.

Hope this helped!

like image 130
jakee Avatar answered Nov 10 '22 11:11

jakee


I agree with @jakee at first part

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

however, listening a global event with "on" may cause a memory leak and zombie view problem and that also causes multiple action handler calls etc.

Instead of "on", you should use "listenTo" in your view

 this.listenTo(vent, "someEvent", yourHandlerFunction);

thus, when you remove your view by view.remove(), this handler will be also removed, because handler is bound to your view.

When triggering your global event, just use

vent.trigger("someEvent",parameters);
like image 8
omeralper Avatar answered Nov 10 '22 13:11

omeralper