Protocol: SC.ObjectMixinProtocol

The SC.ObjectMixinProtocol protocol defines the properties and methods that you may implement in your mixin objects (i.e. JavaScript Objects passed to SC.Object's extend or create) in order to access additional functionality when used. They will be used if defined but are not required.

What is a Mixin?

A mixin, in this context, is a simple JavaScript Object that can be used to provide extra functionality to SC.Object subclasses. While you can mix JavaScript Objects into "classes" (i.e. using SC.mixin(SomeClass)), this particular protocol only refers to mixins in the context of use with an SC.Object "instance" (i.e. SC.Object.create({ ... })).

For example, in order to share a method between two different classes of object, we can use a mixin object that both will consume,

// Common default properties and shared methods which our different classes may consume.
MyApp.MyMixin = {
  a: true,

  aFunc: function () {
    this.set('a', false);
  },

  b: [], // SHARED OBJECT!

  c: {} // SHARED OBJECT!
};

// Two different object types, which both need the functionality provided by MyApp.MyMixin.
MyApp.ObjectType1 = SC.Object.extend(MyApp.MyMixin);
MyApp.ObjectType2 = SC.Object.extend();

obj1 = MyApp.ObjectType1.create();
obj2 = MyApp.ObjectType2.create(MyApp.MyMixin);

// Some proofs.
// 1. The default properties are copied over to the new objects.
obj1.get('a'); // true <--
obj2.get('a'); // true <--

// 2. The primitive properties are unique to each object.
obj1.set('a', false);
obj1.get('a'); // false <--
obj2.get('a'); // true <--

// 3. The methods are copied over to the new objects.
obj1.aFunc; // function () { ... } <--
obj2.aFunc; // function () { ... } <--

// 4. The functions/objects are shared between objects.
obj1.aFunc === MyApp.MyMixin.aFunc; // true <--
obj1.aFunc === obj2.aFunc; // true <--
obj1.b === obj2.b; // true <-- !! Beware of modifying this object !!
obj1.c === obj2.c; // true <-- !! Beware of modifying this object !!

In this example, we used a mixin to share functionality between two classes, which is very easily achieved. There is one issue, that has been known to trip up developers, which should be highlighted. If you set default Objects (e.g. [] or {}) in a mixin, these same Objects will be shared between all of the mixin's consumers.

If you want to set a default Object that is unique to each consumer of the mixin, a better practice is to set it in initMixin() or to check for its existence the first time it is used and only create it then. Note: Do not mix SC.ObjectMixinProtocol into your classes. As a protocol, it exists only for reference sake. You only need define any of the properties or methods listed below in order to use this protocol.*

Defined in: mixin_protocol.js

Class Methods

Class Method Detail

destroyMixin()

This optional method is called to further de-initialize the consumer of the mixin when it is destroyed. When a mixin (i.e. JavaScript Object) is used to extend an SC.Object subclass, we may want to perform additional teardown of the SC.Object instance when it is destroyed according to the needs of the mixin (e.g. to clean up objects that the mixin code initialized and that may otherwise lead to memory leaks). In order to support this, SC.Object will call this method, destroyMixin, if implemented, on each mixin in the order that they were initially added.

For example, if we use two mixins that both de-initialize the same value, the last mixin added would win,

myObject = SC.Object.create(
  // Mixin.
  {
    initMixin: function () {
      // Created extra object for some purpose.
      this.set('anObject', SC.Object.create());
    },

    destroyMixin: function () {
      // Clean up extra object that the mixin is responsible for.
      var anObject = this.get('anObject');
      anObject.destroy();
      this.set('anObject', null);
    }
  });

myObject.get('a'); // false <--

Note, that unlike the similar destroy() method of SC.Object, you do not need to call sc_super in destroyMixin.

initMixin()

This optional method is called to further initialize the consumer of the mixin when it is created. When a mixin (i.e. JavaScript Object) is used to extend an SC.Object subclass, we may want to perform additional set up of the SC.Object instance when it is created according to the needs of the mixin. In order to support this, SC.Object will call this method, initMixin, if implemented, on each mixin in the order that they were added.

For example, if we use two mixins that both initialize the same value, the last mixin added would win,

myObject = SC.Object.create(
  // First mixin.
  {
    initMixin: function () {
      this.set('a', true);
    }
  },

  // Second mixin.
  {
    initMixin: function () {
      this.set('a', false);
    }
  });

myObject.get('a'); // false <--

This was just an example to illustrate the order in which initMixin is called. It is rare that mixins will collide with each other, but it is something to bear in mind when making heavy use of mixins.

Note, that unlike the similar init() method of SC.Object, you do not need to call sc_super in initMixin.

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Apr 08 2015 10:02:21 GMT-0600 (CST)