Chris Dutrow
Chris Dutrow

Reputation: 50412

What is a good method for sending a message from a Child view to its parent Collection view in Backbone.js or Marionette.js?

What is a good method for sending a message from a Child view to its parent Collection view in Backbone.js or Marionettejs?

Normally I send the message through the collection:

ChildView = Backbone.Marionette.ItemView.extend({
     send_message: function(){
          this.model.collection.trigger('some-message');
     }
})

ParentCollectionView = Backbone.Marionette.CollectionView.extend({
     // ON RENDER
     onRender: function(){
          this.listenTo(this.collection, 'some-message', this.do_something);
     }
     // DO SOMETHING
     do_something: function(){
          alert('did something');
     }
});

I think this is not right because:

Instead, I would like to send a message directly from a child view to its parent collection view. (actually, I'm using a composite view, not sure if that matters, wanted to keep the example simple though).

Upvotes: 6

Views: 608

Answers (2)

Alex R
Alex R

Reputation: 624

Marionette has a handy function called triggerMethod that can send events from the child to the parent.

this.triggerMethod("someMethod", data1...)

That event is caught by the parent using an onChildview listener

onChildviewSomeMethod(childView, data1param, ...) {}

Upvotes: 1

nikoshr
nikoshr

Reputation: 33364

Either have the child view directly emit the event and have the parent listen for it :

ChildView = Backbone.Marionette.ItemView.extend({
     send_message: function(){
          this.trigger('some-message');
     }
})

ParentCollectionView = Backbone.Marionette.CollectionView.extend({
     // ON RENDER
     onRender: function(){
          // no idea how Marionette references its children views
          // let's say this.subview is a reference to your child view 
          this.listenTo(this.subview, 'some-message', this.do_something);
     }

    // DO SOMETHING
     do_something: function(){
          alert('did something');
     }
});

Or use a dedicated event emitter you inject into your subview(s)

ChildView = Backbone.Marionette.ItemView.extend({
     send_message: function(){
          this.channel.trigger('some-message');
     }
})

ParentCollectionView = Backbone.Marionette.CollectionView.extend({
     initialize: function(){
          this.channel = _.extend({}, Backbone.Events); 
          this.listenTo(this.channel, 'some-message', this.do_something);
     },
     // ON RENDER
     onRender: function(){
          // pass the channel to the child
          // that probably should be done when the child is created
          this.subview.channel = this.channel;
     },
     // DO SOMETHING
     do_something: function(){
          alert('did something');
     }
});

Upvotes: 5

Related Questions