Provide a mixInto function to mix a source's functions in to a target
As noted in my blog post on Mixins (http://lostechies.com/derickbailey/2012/10/07/javascript-mixins-beyond-simple-object-extension/) I would like to be able to mix a specific function from a source object in to a target object.
I added a mixInto function on to Backbone.Augment so that this can be done. As an example:
aug = {
augment: function(t){
Backbone.Augment.mixInto(t, this, "foo");
},
foo: function(){
console.log("I'm the foo function!")
}
};
Target = Backbone.Model.extend({});
Target.prototype.augment(aug);
target = new Target();
target.foo(); // => "I'm the foo function!"
In order to make this work the way I would like to see it work, I needed to be able to augment a Backbone object's prototype, not just the type itself. As shown in this example, you can now augment a prototype directly:
Backbone.Model.prototype.augment(...)
This gives us more flexibility in augmenting either a base Backbone type or it's prototype, explicitly.
... I suppose I should update the docs for this, too...
I have some questions about this, and I don't think it's ready to be pulled in...
Context vs Target
the context of the mixed in function is always set to the source object - the augmenting object. what if we need access to the target object during the augmenting function's execution? would it make sense to provide the target object as the first parameter to the mixed in function?
aug = {
// ...
foo: function(target, other, parameters){
// do stuff with the `target` instance, here
}
}
This would limit our ability to mix objects that were not designed to work with Augment in to other objects, though. Is there a better way to be able to get access to the target object in the mixed in function?
issue #3 might be able to solve this problem. i can get a reference to the target from the constructor:
aug = {
augment {
constructor: function(target){
this.target = target;
Backbone.Augment.mixInto(target, this, "foo");
}
},
foo: function(){
this.target.doSomething();
}
}
I'm wondering if we should extract ideas like this out into a plugin pattern or using it's own library, like what it seemed like you were on to with Catalina.
That way we can extend that as much as we want and augments that depend on Catalina will simply just depend on Catalina.
I can see your idea being much more valuable outside of even Backbone itself, let alone this augment api. augment, at its core, could just be a stopgap that enables better modularity and abstraction. Something, ideally, we wouldn't even need to have done but seemed to be a necessity at the time.