I’ve continued to enjoy using Backbone.js to build single page apps. As I’ve seen more and more real world backbone I’ve started to develop opinions to augment the blissfully unopinionated little framework that could.
One of these opinions has turned into a mini-library: Cocktail adds functionality to Backbone’s extend to facilitate breaking up reusable code into mixins. It’s pretty straightforward:
Define your mixin. Mixins are just plain vanilla JavaScript objects with methods and properties hanging off of them. Here’s a slightly contrived mixin that makes a view selectable:
window.MyMixins = {}; MyMixins.SelectMixin = { initialize: function() { this.model.on('change:selected', this.refreshSelect, this); }, events: { click: 'toggleSelect' }, render: function() { this.refreshSelect(); }, refreshSelect: function() { this.$el.toggleClass('selected', this.model.get('selected')); }, toggleSelect: function() { this.model.set('selected', !this.model.get('selected')); } }Mix your mixin into your views. It’s a one-liner:
var MyView = Backbone.View.extend({ mixins: [MyMixins.SelectMixin, MyMixins.SomeOtherMixin], events: { 'click .myChild': 'myCustomHandler' } initialize: function() { ... }, render: function() { ... }, etc... });That’s it! Instances of
MyViewwill automatically inherit the behaviors and methods defined inSelectMixin.
Cocktail brings two simple things to the table:
- it adds the special
mixins:[...]notation to Backbone’sextend. - it automatically detects and handles method collisions. In the example above Cocktail will wrap
MyView‘s andSelectMixin‘s implementations ofinitializeinto one method and assign that method to the new, composite, class. The return value of this composite method is the last non-undefinedvalue returned by the methods it wraps. All colliding methods are handled this way, as is theeventshash (theeventshashes all get merged together).
There are more details and examples at the repo. In particular, there’s an example for testing mixins with Jasmine — it goes over a pattern for writing shared behaviors in Jasmine.