Built-in Triggers
Marionette views include a set of built-in triggers that are fired throughout the View creations and destruction lifecycle. These triggers are designed to give you more fine-grained control over your view, for example being able to modify your template before it gets attached to your page, or even before the template gets rendered.
It's also possible to write your own custom triggers and handlers to provide hooks for specific actions that aren't provided by Marionette.
Listening for triggers
To listen to a trigger, we can attach a handler to our view:
// Listen to the 'render' trigger
view = new Marionette.LayoutView();
view.listenTo('render', function() {
console.log('View was rendered');
});
// Listen to the 'before:attach' trigger
view.listenTo('before:attach', function() {
console.log('View is about to be attached to the page');
});
Most triggers have before:action
and action
hooks that fire before and after
action
has occurred. A common example could be before:render
and render
which fire before and after the template is rendered.
Short-hand
All triggers that get fired can also be handled by defining methods in a
specific style on our views: the onTriggerFired
format e.g. onBeforeRender
.
To know what name our handler method requires, we simply take the trigger name
(before:render
in this case), prefix on
and uppercase the first letter and
every first letter following a :
in the name. So render
becomes onRender
,
before:render
becomes onBeforeRender
, attach
becomes onAttach
, etc.
An example should help explain:
var MyLayout = Marionette.LayoutView.extend({
onBeforeRender: function() {
console.log('before:render was fired');
},
onRender: function() {
console.log('render was fired');
}
});
For simplicity, this reference will use the trigger:fired
format, which you
should now be able to convert to the method name using the formula described
above.
List of View Triggers
This reference lists all the triggers that can be fired in alphabetical order,
with the before:<trigger>
as part of the <trigger>
section. We'll list the
view types that can fire each trigger (or all), and what each trigger means to
you. Where appropriate, we'll provide an example of common use of the trigger.
If you just want to know what triggers a view can fire, skip to the bottom of this reference to find the list of views and the triggers they can each fire.
add:child
and before:add:child
This trigger fires whenever a child view gets rendered and attached to the
CollectionView
. We will get an argument referencing the child that has just
been added. This can be useful if you need to do some extra work on the child
view where you need information from the parent.
Example
On Views
CollectionView
CompositeView
attach
and before:attach
This trigger fires once our view gets attached to the actual DOM i.e. once the view is completely rendered and viewable in the browser window. This is usually used to perform actions that require the view to be completely rendered and visible - for instance displaying a modal or datepicker widget. We also use this as a safe point where we know that the view is finished and active for the user.
Example
This example uses Bootstrap's Modal JavaScript which requires the HTML to be attached to the DOM to work.
var ModalLayout = Marionette.Layout.extend({
ui: {
wrapper: '.modal-wrapper'
},
/** Use Bootstrap's modal JavaScript. This assumes that the JS files are
* loaded and will work.
*/
onAttach: function() {
this.ui.wrapper.modal('show');
}
});
On Views
View
ItemView
LayoutView
CollectionView
CompositeView
destroy
and before:destroy
Fired by the region manager to perform any extra clean up on the view after it has been destroyed. This can be things like executing extra JS on plugins like modals and datepickers.
Example
In this example, we'll use the before:destroy
trigger to close a modal before
it gets removed from the DOM. We're using something similar to
Bootstrap's modal JavaScript.
var ModalView = Marionette.LayoutView.extend({
ui: {
wrapper: '.modal-wrapper'
},
onBeforeDestroy: function() {
this.ui.wrapper.modal('hide');
}
});
As an aside, this wouldn't work in Bootstrap as the modal
method returns
immediately, causing the view to be destroyed before the modal can be hidden.
On Views
View
ItemView
LayoutView
CollectionView
CompositeView
dom:refresh
Only fired when a view is re-rendered. This does not get fired on the first render, only on subsequent rendering.
Example
This example demonstrates when the dom:refresh
trigger is fired.
var MyLayout = Marionette.LayoutView.extend({
onDomRefresh: function() {
console.log('dom:refresh');
},
onRender: function() {
console.log('render');
},
onShow: function() {
console.log('show');
}
});
var view = new MyLayout();
regionManager.get('layout').show(view);
// 'render'
// 'show'
view.render();
// 'render'
// 'dom:refresh'
On Views
View
ItemView
LayoutView
CollectionView
CompositeView
render
and before:render
The render
event fires when the view's HTML template has been rendered
(the string has been built) but before it gets attached to the browser DOM. We
commonly use this hook to operate on the HTML but before the user can see it.
Example
A common example is to check for data and add/remove classes on the view's element every time it gets rendered. This example checks to see if a table row was selected for a form element and attaches the appropriate class.
var RowView = Marionette.LayoutView.extend({
tagName: 'tr',
onRender: function() {
if (this.model.get('selected')) {
this.$el.addClass('selected');
}
else {
this.$el.removeClass('selected');
}
}
});
var TableView = Marionette.CompositeView.extend({
tagName: 'table',
childView: RowView,
childViewContainer: 'tbody'
});
On Views
ItemView
LayoutView
CollectionView
CompositeView
render:collection
and before:render:collection
Fired after the collection has been rendered and attached to the view. This will
only fire if the view's collection is not empty. In other words, if the view
attached to emptyView
is displayed, this trigger won't be fired.
render:empty
and before:render:empty
Fired after the emptyView
has been rendered.
On Views
CollectionView
CompositeView
render:template
and before:render:template
The render:template
trigger is fired when the wrapper template for a
CompositeView
is rendered but before the collection items have started
rendering - childViewContainer
will be empty while this trigger is first
fired.
Example
On Views
CompositeView
reorder
and before:reorder
Gets fired whenever we reorder the underlying collection attached to a view.
Example
On Views
CollectionView
CompositeView
remove:child
and before:remove:child
The remove:child
trigger gets fired when a collection item is removed,
typically when this.collection.remove(id)
is called. Unlike the collection
event, this fires after the view has been removed from the DOM.
Example
On Views
CollectionView
CompositeView
show
and before:show
The show
event fires when region.show(view)
- or
layoutView.showChildView(view)
- is complete. We'll commonly use this trigger
to build up our nested layout hierarchy and show a layout's sub-views.
Example
Our example is a Marionette pattern that is commonly used to build up our view
hierarchy by chaining show
handlers.
var MyLayout = Marionette.LayoutView.extend({
regions: {
todoList: '.todo-hook'
},
onShow: function() {
console.log('regionManager has show this view');
this.showChildView('todoList', new CompositeView({
collection: this.collection
}); // This will trigger CompositeView's 'before:show' and 'show' handlers
}
})
// Assuming regionManager has been defined with a region 'layout'
regionManager.get('layout').show(new MyLayout({collection: todoList}));
On views
View
ItemView
LayoutView
CollectionView
CompositeView
List of Views and their Triggers
The Marionette view lifecycle involves firing a number of triggers at each stage of its creation. The exact lifecycle depends on how the view is displayed and what type of view it is.
This diagram displays the full lifecycle. Our before:add:child
and add:child
only get called on CollectionView
and CompositeView
before the view
lifecycle of each child is executed.
Our before:show
and show
triggers get fired whenever the view is shown as
part of a usual lifecycle - from region.show(view)
,
view.showChildView(view)
, or when a new child is added to a CollectionView
with view.collection.add(model)
.
Views and their Triggers
Included below is a reference to all the in-built view triggers and the views that can trigger them:
View |
ItemView |
LayoutView |
CollectionView |
CompositeView |
|
---|---|---|---|---|---|
add:child |
✓ | ✓ | |||
attach |
✓ | ✓ | ✓ | ✓ | ✓ |
destroy |
✓ | ✓ | ✓ | ✓ | ✓ |
dom:refresh |
✓ | ✓ | ✓ | ✓ | ✓ |
render |
✓ | ✓ | ✓ | ✓ | ✓ |
render:collection |
✓ | ✓ | |||
render:template |
✓ | ||||
reorder |
✓ | ✓ | |||
remove:child |
✓ | ✓ | |||
show |
✓ | ✓ | ✓ | ✓ | ✓ |