EmberJS Mixins

In EmberJS the Mixin class can create objects whose properties and functions can be shared amongst other classes and instances. This allows for an easy way to share behavior between objects as well as design objects that may need multiple inheritance.

Mixins are great for abstracting pieces of reusable code into smaller single responsibility objects. For larger applications this makes code easier to reason about and easier to test.

App.HelloMixin = Ember.Mixin.create({
  sayHello: function() {
    alert("Hello " + this.get('name'));
  }
});

The mixin can then be added to any class with the extend function.

App.Person = Ember.Object.extend(App.HelloMixin);
App.Product = Ember.Object.extend(App.HelloMixin);

ryan = App.Person.create({ name: 'ryan' });
book = App.Product.create({ name: 'A Storm of Swords' });

ryan.sayHello(); // "Hello ryan"
book.sayHello(); // "Hello A Storm of Swords"

Examples

Mixins are applicable to all class of Ember including models, controllers, and views. This allows you to take advantage of some specific idioms and conventions that exist in Ember.

A mixin can be used to quickly wire up controllers that may depend on another controller. For example, a couple of controllers might need access to the application's current user.

App.CurrentUserMixin = Ember.Mixin.create({
  needs: 'currentUser',
  currentUser: Ember.computed.alias('controllers.currentUser')
});

App.ProfileController = Ember.ObjectController.extend(
  App.CurrentUserMixin, {

  isCurrentUsersProfile: function() {
    return this.get('currentUser.model') === this.get('model');
  }.property('currentUser.model', 'model');
});

The same can be done if views need to share a common piece of code. Imagine a view that wants to use jQuery UI's resizable feature.

App.ResizableViewMixin = Ember.Mixin.create({
  didInsertElement: function() {
    this.$().resizable();
  }
});

App.PictureView = Ember.View.extend(App.ResiableViewMixin);

Mixins at Runtime

Mixins can also be applied to instances of objects at runtime. This allows for only certain objects to gain behavior.

App.Coffee = Ember.Object.extend();

starbucks = App.Coffee.create({ name: 'Starbucks' });
dunkindonuts = App.Coffee.create({ name: 'Dunkin Donuts' });

App.HelloMixin.apply(starbucks);

starbucks.sayHello(); // "Hello Starbucks"
dunkindonuts.sayHello(); // No method error

Mixin Detection

An object can quickly be checked for the presence of a mixin using the detect function. Building off the example above.

App.HelloMixin.detect(starbucks) // => true
App.HelloMixin.detect(dunkindonuts) // => false

Included Mixins

Ember comes with many mixins available to use in any class or instance. There are mixins to deal with a very wide range of abstractions such as immutability, sorting, enumeration, and events. A full list of mixins can be found in ember-runtime.

Ryan Toronto

Ember developer & Basketball fan