Linda Keating
Linda Keating

Reputation: 2435

Marionette trigger method and listenTo

I have two ItemViews.

The first view should trigger an event, and the second view should listen for the trigger. How should I go about it?

Here's what I have so far:

  Branch.RecipeView = Marionette.ItemView.extend({
    triggers: {
      'change': 'recipe:selected'
    }
  });

And then the second View is as follows:

  Branch.MetaDataView = Marionette.ItemView.extend({
    template: _.template(
      '<div id="branchImgSrc">' +
       '</div>' 
    ),
  initialize: function () {
    this.on('recipe:selected', function () {
       console.log('selected');
    });
  }
});

I instantiate both views and add them to the layout, but the event in ItemView one never triggers the recipe:selected in ItemView number 2.

Am I thinking about this the wrong way?

Upvotes: 1

Views: 1649

Answers (1)

Lochlan
Lochlan

Reputation: 2786

The answer to your question depends on whether or not you want Branch.MetaDataView to store a reference to Branch.RecipeView, as opposed to using some external mechanism for the event messaging.

  1. If you don't mind referencing Branch.RecipeView you can get what you want with listenTo:

    recipeView = new Branch.RecipeView();
    
    Branch.MetaDataView = Marionette.ItemView.extend({
      template: _.template(
        '<div id="branchImgSrc">' +
         '</div>' 
      ),
      initialize: function () {
        this.listenTo(recipeView, 'recipe:selected', function () {
          console.log('selected');
        });
      }
    });
    
  2. If you don't want to reference one view from the other directly, then you can use some other mechanism for carrying your 'recipe:selected' event. This could be the DOM, or this could be some kind of messaging-bus object (something like Backbone.Radio or even just _.extend({}, Backbone.Events);).

    Going through the DOM might make sense if your Branch.RecipeView is a child/descendent of Branch.MetaDataView's el, as then you would get to use event bubbling as your message passing mechanism. To do so would require triggering an event on Branch.RecipeView's $el and then creating a .on listener and callback on Branch.MetaDataView (and don't forget to remove the listener when destroying the view!).

    If you want to use a messaging object (which is definitely the best approach if you aren't emitting the event from a child/descendent view) just take a look at the Backbone.Radio readme, particuarly the Backbone.Events section for the simplest example:

    // Create a message bus
    var myBus = _.extend({}, Backbone.Events);
    
    // Listen in on the message bus
    this.listenTo(myBus, 'some:event', myCallback);
    
    // Trigger an event on the bus
    myBus.trigger('some:event');
    

Upvotes: 2

Related Questions