How to be DRY with Marionette Behavior

This post is a part of Get Noticed! 2017 contest by Maciej Aniserowicz

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…

Stay DRY. Photo credits: Adam Kontor.

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.