Marionette Application, View and CollectionView and ES 6 Class syntax

ES 6 classes with Marionette may introduce some problems. Photo credits: Pixabay

At least for now, ES 6 classes are not best friends of Marionette elements: Application, View or CollectionView. But fortunately, there is few smart workarounds, including one which is quite easy to use.

ES 6 classes

This is one of the most expected features for many years (especially by people coming from Java/C# worlds), in the same time one of the most hated by old-school JS developers: JavaScript Class syntax. And there we should remember two most important, for my opinion, things about ES 6 classes:

  1. This is only syntax sugar around well-known Prototype, so on the one hand, it is possible that in some situations it may confuse Java/c# newcomers, but on the other hand — these situations should be quite rare, and it makes migration from Prototype to Class syntax easier.
  2. Everything in class runs in strict mode.

I think class syntax make code much more clean and easier to read.

Unexpected problems

Unfortunately, it does not work well with Backbone and Marionette:

Backbone relies on adding properties to a class’ prototype before a class’ constructor is invoked 1. ES6 classes don’t provide any way to define properties on the prototype as part of the class definition

You can read more here: Why Backbone.js and ES6 Classes Don’t Mix.

Solutions

Fortunately, on the same blog I found a post with solutions: Backbone and ES6 Classes Revisited.

Treat everything as method

One of the solutions is especially helpful for me (same post):

Backbone evaluates all of its properties using Underscore’s _.result function. _.resultchecks to see if an object property is a function. If it is then _.result will evaluate it and return the result. This allows Backbone to accept its properties as either an object or a function. Very handy. So one workaround to the constructor problem is to make everything a method, including properties.

In my opinion it requires from me as little changes as possible, I don’t need to add any superfluous methods.

Example

As a proof of concept, I rewrote few classes from Backbone’s extend to native ES Class, for example — Application class (app.js):

class Application extends Mn.Application {
channelName () {
return "chessboardMoves";
}
radioEvents () {
return {
"move": "onMove"
};
}
onMove (move) {
alert(`Move: ${JSON.stringify(move)}`);
}
}

The only significant change is that channelName, previously bound as as string, becomes a method returning string.

Conclusion

I didn’t expect this problem with rather basic feature of ES 6, and I would like to thank Ben McCormick to provide a smart solutions.