jsoverson / backbone.augment Goto Github PK
View Code? Open in Web Editor NEWSimple plugin/addon functionality for Backbone Views, Models, and Collections.
Simple plugin/addon functionality for Backbone Views, Models, and Collections.
I was reading @derickbailey's blog post on mixins on los techies (http://lostechies.com/derickbailey/2012/10/07/javascript-mixins-beyond-simple-object-extension/) where he sugested a handy way of mixing a component into a target object: https://gist.github.com/3847156#file_5.js
While I liked the idea, I thought it might become tedious to have to define which properties should and should not be mixed into the target object.
I can imagine a scenario where you might design components specifically with the intention to mix them into other objects. An example of this might be Backbone.EventBinder. In this case, the designer of the component has a very clear idea of which methods and/or properties should be mixed into the target object, and which should not.
I think it would be easier to create a facade, containing only the methods and properties you want to mix into the target object, while keeping the internals of the component private.
This way @derickbailey's gist could still take a target, and a source, but you would no longer need to explicitly list the method names you want to mix into the target. Instead the source's facade already contains only the methods you want to mix in. It would then be desirable to make the methodNames argument(s) optional:
// build a mixin function to take a target that receives the mixin,
// a source that is the mixin, and a list of methods / attributes to
// copy over to the target
function mixInto(target, source, methodNames){
// ignore the actual args list and build from arguments so we can
// be sure to get all of the method names
var args = Array.prototype.slice.apply(arguments);
target = args.shift();
source = args.shift();
methodNames = args;
// builds a function with a closure around the source
// and forwards the method call to the source, passing
// along the method parameters and setting the context
var mixMethod = function(target, source, method) {
target[method] = function(){
var args = Array.prototype.slice(arguments);
source[method].apply(source, args);
}
}
// if any method names are supplied, only those methods should be
// mixed into the target
if(methodNames.length) {
var length = methodNames.length;
for(var i = 0; i < length; i++){
mixMethod(target, source, methodNames[i]);
}
}
// if no method names are supplied, all properties of the source
// should be mixed into the target (leaving it upto the source
// to expose it's public api)
else {
for(var method in source) {
if(source.hasOwnProperty(method) && typeof source[method] === 'function') {
mixMethod(target, source, method);
}
}
}
}
All of the examples I've built, and the ones I see in the docs, assume an object literal for the augmenting object. What about object instances? How would we get an object like Backbone.EventBinder to mix an instance of itself in to a Backbone.View?
I think if we look at the augmenting object as an adapter this might work:
eventBinderAug = {
augment: function(target){
_.wrap(target.constructor, function(original, options){
var eventBinder = new Backbone.EventBinder();
Backbone.Augment.mixInto(this, eventBinder, "bindTo", "unbindFrom", "unbindAll");
original(options);
});
}
};
MyView = Backbone.View.extend({});
MyView.augment(eventBinderAug);
What I really want to do, is have a way to use an existing constructor function as an augmenter for each instance of the target... which this does... but is this the best way to make this happen? It seems like it might be a bit cumbersome to do it this way.
Is there something we can do to make this easier?
One idea I had was to provide a way to hook in to the lifecycle of a given object.
eventBinderAug = {
augment: {
// fires during the construction of the target
constructor: function(target, options){
target.eventBinder = new Backbone.EventBinder();
Backbone.Augment.mixInto(target, target.eventBinder, "bindTo, "unbindFrom", "unbindAll");
},
// fires just before the `initialize` function of the target
initialize: function(options){
// ...
}
}
};
MyView = Backbone.View.extend({});
MyView.augment(eventBinderAug);
var v = new MyView();
v.bindTo( ... );
When the augment is set up, it would override the specified functions of the target object to run the augment's function as well as the original target's function. So the end result would look something like this:
for (var method in augment){
if (augment.hasOwnProperty(method){
_.wrap(target[method], function(original, options){
augment[method].call(augment, target, options);
original(options);
}
}
}
This hack wouldn't really work for all the types of objects we can augment, but it should get the idea across, I think.
The intent is that we should be able to augment Backbone types and provide methods like constructor
, initialize
, dispose
and even render
or other methods that we want, without forcing the person writing the augmentation to have to call the whole Backbone.Whatever.prototype.method chain.
This would solve the problem of augmenting instances with instances, and also give a lot of value in the ability to augment the lifecycle and existing methods of a backbone object type.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.