Marionette Application, View and CollectionView and ES 6 Class syntax
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:
- 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.
- 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._.result
checks 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.