22

I have a main view and inside that main view I have another view that gets created when I click a button. Is there a way to listen for a custom event on the parent view for an event that is fired from the child view. I tried to do it through the el property using jQuery trigger but that didn't quite work.

gutch
  • 6,959
  • 3
  • 36
  • 53
Chapsterj
  • 6,483
  • 20
  • 70
  • 124

3 Answers3

44

Ya, no problem... you'll want to use the "Event Aggregator" pattern. It's 1 line of code in Backbone:

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

Now can you trigger / bind to events from this object, everywhere in your app, and have the different parts of your app communicate with each other in a decoupled manner.

I use this a LOT!

I also blogged more about it here: http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/

Derick Bailey
  • 72,004
  • 22
  • 206
  • 219
  • 14
    +1. I take it a step further and inject the event aggregator into every view: `Backbone.View.prototype.eventAggregator = _.extend({}, Backbone.Events);`. By doing that, every view gets the event aggregator every time it gets constructed. – Brian Genisio Oct 21 '11 at 00:35
  • 3
    Isn't your event aggregator just a simplified "view state model"? Wouldn't `viewModel = new Backbone.Model()` by more elegant? At least that way disparate views could bind to *changes* in the view model, rather than arbitrary events. Eg `viewModel.bind('change:selectedFoo', aView.render)` vs `eventAgg.bind('selectedFooChanged', aView.render)`. Thoughts? – Crescent Fresh Oct 21 '11 at 09:11
  • 2
    @crescent fresh - no. a model has semantic meaning, being a stateful representation of some entity. it has attributes and methods that manipulate those attributes. an event aggregator is a stateless object that only coordinates parts of the system, through the use of events, allowing a more decoupled architecture. http://martinfowler.com/eaaDev/EventAggregator.html – Derick Bailey Oct 21 '11 at 12:09
  • I added it to my `BaseView`, which already extends `Backbone.View` to add some other functionality: `eventAggregator: _.extend {}, Backbone.Events`. All my views inherit from `BaseView` and `Backbone.View` is left unscathed for other use, if needed. My original old BaseView can be seen here: https://gist.github.com/1515914 – wulftone Mar 30 '12 at 21:24
  • @CrescentFresh - having a global viewmodel track changes does seem more robust and easier to maintain. Plus, any new views added after an 'event' is sent can see the current state and adjust themselves appropriately. Have you tried using it in any real code? – Allan May 16 '12 at 18:39
  • 1
    @Allan: yes actually. In production apps we use this "global" view state model (I don't mean a global variable) that tracks the current state of the app. Things like the currently selected foo, the current map center (geo coordinates), the full list of all foos, etc etc. It's where views put their view "state". And we get the event aggregation for free ;) As the view state changes, other disparate views can adjust themselves accordingly without knowing who or why the state has changed. – Crescent Fresh May 17 '12 at 00:10
  • @BrianGenisio How would you refer to the aggregator in the view using your event aggregator injection? Would it be this.eventAggregator? – Not a machine Nov 27 '18 at 17:49
2

Here is another approach, that might be more intuitive for people who are looking for a simple way to "bubble" events up from a child view to a parent view:

https://github.com/dgbeck/backbone.courier

There is some discussion in the readme on how it compares to event aggregators.

Brave Dave
  • 1,300
  • 14
  • 9
0

Rolling your own "event aggregator" or mediator or pubsub (as easy as it is described above) is not necessary since Backbone mixes in the Events object directly to the Backbone object in their namespace. Here's a link to the source code and their documentation on the implementation.

Allow the Backbone object to serve as a global event bus, for folks who want global “pubsub” in a convenient place.

Adam
  • 1
  • 1