How to be DRY with Marionette Behavior
Marionette Behavior is a class which can help you to Don’t Repeat Yourself, when it comes to common behavior, like reacting on clicks, rendering etc…
You are WET
(Abbreviation of We Enjoy Typing or Write Everything Twice), when you have the same code in many places, which is often a result of copy-paste development. Why is it bad? Cause when behavior will change, you will have to make changes in many places — it’s easy to forget something, to make a typo or to accidentally change something else.
You are DRY
When you Don’t Repeat Yourself. If you replace code repetition with one (or two, three… Still better that twenty) abstraction containing logic, you make change only in one place. Also, if you want to change or improve something, you change only one file — there is less risk that you accidentally break unrelated feature.
Marionette Behavior
Marionette behavior, for me, is something like AngularJS component (or older directive), like textarea encapsulated in component. It encapsulates some parts of common logic, repeated earlier across application.
Where I found a place to try Marionette Behaviors and be little more DRY? In row views.
Here’s repetitive code, first in white-row-view
:
onRender: function () {
this.$el.addClass("row-section starts-with-white");
this.$el.attr("id", `row-${this.model.get("index") - 1}`);
},
And˛in black-row-view
:
onRender: function () {
this.$el.addClass("row-section starts-with-black");
this.$el.attr("id", `row-${this.model.get("index") - 1}`);
},
Only difference is second class name. So how can it be more generic? Let’s see created Behavior:
const Mn = require("backbone.marionette");
return Mn.Behavior.extend({
defaults: {
color: "unset",
},
onRender: function () {
this.$el.addClass(`row-section starts-with-${this.getOption("color")}`);
this.$el.attr("id", `row-${this.view.model.get("index") - 1}`);
}
});
this.$el
is proxy for $el
from view which will use this Behavior. And this.view
is reference to this view, it gives access to view’s model.defaults
can be overridden in view declaration, you can access it with getOption(optionName)
method.
How to use it? Like this (white-row-view
):
behaviors: [
{
behaviorClass: RowOrderBehavior,
color: "white",
},
],
onRender
was replaced˛with behavior, cause now onRender
sits in Behavior. In black-row-view
it is used in the same way, with color
set to black
.
Conclusion
Although it’s simple, Marionette Behavior is important part of Marionette ecosystem, and definitely I will use it many times.