Marionette.js. Events. Triggering Events on Child Events

Marionette 3 adds a new feature that allows selected events to fire events directly, allowing them to be propagated up the view hierarchy more easily and explicitly. The values of the hash should be a string of the event to trigger on the parent.

by marionettejs

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.radio/2.0.0/backbone.radio.min.js"></script>
<script src="https://rawgit.com/marionettejs/backbone.marionette/next/lib/backbone.marionette.js"></script>

JavaScript

const { View, CollectionView } = Marionette; // import { View, CollectionView } from 'backbone.marionette';


const collection = new Backbone.Collection([
	{title: 'Item 1'},
	{title: 'Item 2'},
  {title: 'Item 3'}
]);

const ChildView = View.extend({
	template: _.template(`
    <form>
      <input type='text' value='<%= title %>'>
      <input type='submit' class='button' value='Submit'>
    </form>
    <hr/>
  `),
  // Events hash defines local event handlers that in turn may call `triggerMethod`.
  events: {
    'click .button': 'onClickButton'
  },

  triggers: {
    'submit form': 'submit:form'
  },

  onClickButton() {
    // Both `trigger` and `triggerMethod` events will be caught by parent.
    this.trigger('show:message', 'foo');
    this.triggerMethod('show:message', 'bar');
  }
});

// The parent uses childViewEvents to catch the child view's custom event
const ParentView = CollectionView.extend({
  childView: ChildView,

  childViewTriggers: {
    'show:message': 'child:show:message',
    'submit:form': 'child:submit:form'
  },

  onChildShowMessage(message) {
    console.log('A child view fired show:message with ' + message);
  },

  onChildSubmitForm(childView) {
    console.log('A child view fired submit:form');
  }
});

const GrantParentView = View.extend({
	template: _.template('<div class="list"></div>'),
  collection: collection,
  regions: {
    list: '.list'
  },

  onRender() {
    this.showChildView('list', new ParentView({
      collection: this.collection
    }));
  },

  childViewEvents: {
    'child:show:message': 'showMessage'
  },

  showMessage(childView) {
    console.log('A child (' + childView + ') fired an event');
  }
});

const grantParentView = new GrantParentView();
grantParentView.render();

$('body').append(grantParentView.$el);