milo-core

Mixin

function
Mixin() ->Mixin

Option name Type Description
hostObject Object

Optional object where a Mixin instance will be stored on. It is used to proxy methods and also to find the reference when it is needed for host object implementation.

proxyMethods Object

Optional map of proxy method names as keys and Mixin methods names as values, so proxied methods can be renamed to avoid name-space conflicts if two different Mixin instances with the same method names are put on the object

arguments List

all constructor arguments will be passed to init method of Mixin subclass together with hostObject and proxyMethods

return Mixin

milo.classes.Mixin - an abstract Mixin class.
Can be subclassed using:

var MyMixin = _.createSubclass(milo.classes.Mixin, 'MyMixin');

Mixin pattern is also used, but Mixin in milo is implemented as a separate object that is stored on the property of the host object and can create proxy methods on the host object if required.
Classes Messenger and MessageSource are subclasses of Mixin abstract class. this in proxy methods refers to Mixin instance, the reference to the host object is this._hostObject.

function Mixin(hostObject, proxyMethods) { // , other args - passed to init method
    check(hostObject, Match.Optional(Match.OneOf(Object, Function)));

    // store hostObject
    _.defineProperty(this, '_hostObject', hostObject);

    // proxy methods to hostObject
    if (proxyMethods)
        this._createProxyMethods(proxyMethods);

    // calling init if it is defined in the class
    if (this.init)
        this.init.apply(this, arguments);
}

Mixin instance methods

These methods are called by constructor, they are not to be called from subclasses.

_.extendProto(Mixin, {
    _createProxyMethod: _createProxyMethod,  // deprecated, should not be used
    _createProxyMethods: _createProxyMethods  // deprecated, should not be used
});

Mixin class methods

These method should be called in host class declaration.

_.extend(Mixin, {
    useWith: Mixin$$useWith
});

_createProxyMethod

function
_createProxyMethod()

Option name Type Description
mixinMethodName String

name of method in Mixin subclass

proxyMethodName String

name of created proxy method on host object

hostObject Object

Optional reference to the host object; if not specified the host object passed to constructor wil be used. It allows to use the same instance of Mixin on two host objects.

Creates a proxied method of Mixin subclass on host object.

function _createProxyMethod(proxyMethodName, mixinMethodName, hostObject) {
    hostObject = hostObject || this._hostObject;

    // Mixin class does not allow shadowing methods that exist on the host object
    if (hostObject[proxyMethodName])
        throw new Error('method ' + proxyMethodName +
                        ' already defined in host object');

    var method = this[mixinMethodName]
    check(method, Function);

    // Bind proxied Mixin's method to Mixin instance
    var boundMethod = method.bind(this);

    _.defineProperty(hostObject, proxyMethodName, boundMethod, _.WRIT);
}

_createProxyMethods

function
_createProxyMethods()

Option name Type Description
proxyMethods

map of names of methods, key - proxy method name, value - mixin method name. Can be array.

hostObject Object

an optional reference to the host object; if not specified the host object passed to constructor wil be used. It allows to use the same instance of Mixin on two host objects.

Creates proxied methods of Mixin subclass on host object.

function _createProxyMethods(proxyMethods, hostObject) {
    check(proxyMethods, Match.Optional(Match.OneOf([String], Match.ObjectHash(String))));

    // creating and binding proxy methods on the host object
    if (Array.isArray(proxyMethods))
        proxyMethods.forEach(function(methodName) {
            // method called this way to allow using _createProxyMethods with objects
            // that are not inheriting from Mixin
            _createProxyMethod.call(this, methodName, methodName, hostObject);
        }, this);
    else
        _.eachKey(proxyMethods, function(mixinMethodName, proxyMethodName) {
            // method called this way to allow using _createProxyMethods with objects
            // that are not inheriting from Mixin
            _createProxyMethod.call(this, proxyMethodName, mixinMethodName, hostObject);
        }, this);
}

Mixin$$useWith

function
Mixin$$useWith()

Option name Type Description
this Function

Mixin subclass (not instance)

hostClass Object

host object class; must be specified.

instanceKey String

the name of the property the host class instance will store mixin instance on

mixinMethods

map of names of methods, key - host method name, value - mixin method name. Can be array.

Adds methods of Mixin subclass to host class prototype.

function Mixin$$useWith(hostClass, instanceKey, mixinMethods) {
    check(mixinMethods, Match.Optional(Match.OneOf([String], Match.ObjectHash(String))));

    if (Array.isArray(mixinMethods))
        mixinMethods.forEach(function(methodName) {
            Mixin_addMethod.call(this, hostClass, instanceKey, methodName, methodName);
        }, this);
    else
        _.eachKey(mixinMethods, function(mixinMethodName, hostMethodName) {
            Mixin_addMethod.call(this, hostClass, instanceKey, mixinMethodName, hostMethodName);
        }, this);
}