Created
April 22, 2015 02:17
-
-
Save colllin/17b9da4c7c51168953ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
Backbone.Events.autorun = function(f, context) { | |
if (!this.__autorunHandles) this.__autorunHandles = []; | |
var backboneContext = this; | |
var handle = Tracker.autorun(function() { | |
Tracker.currentComputation.__backboneContext = backboneContext; | |
f(); | |
}); | |
this.__autorunHandles.push(handle); | |
return handle; | |
}; | |
Backbone.Events.stopListening = _.wrap(Backbone.Events.stopListening, function(bbStopListening, subject) { | |
// If stopListening is called without a subject, stop all running computations. | |
if (!subject && this.__autorunHandles) { | |
for (var i = 0; i < this.__autorunHandles.length; i++) { | |
this.__autorunHandles[i].stop(); | |
} | |
} | |
return bbStopListening.apply(this, Array.prototype.slice.call(arguments, 1)); | |
}); | |
_([Backbone, Backbone.Model.prototype, Backbone.Collection.prototype, Backbone.View.prototype, Backbone.Router.prototype, Backbone.History.prototype]).each(function(hasEvents) { | |
_.extend(hasEvents, { | |
autorun: Backbone.Events.autorun, | |
stopListening: Backbone.Events.stopListening | |
}); | |
}); | |
// Wrap all Backbone.Model accessor functions to establish dependencies on any active computations. | |
var establishModelDependency = function(model, listener, attr) { | |
if (!model.__dependencies) model.__dependencies = []; | |
var dependency = new Tracker.Dependency(); | |
dependency.depend(); | |
var depChanged = function() { | |
dependency.changed(); | |
}; | |
listener.listenTo(model, attr ? 'change:'+attr : 'change', depChanged); | |
Tracker.currentComputation.onInvalidate(function() { | |
listener.stopListening(model, attr ? 'change:'+attr : 'change', depChanged); | |
}); | |
}; | |
Backbone.Model.prototype.get = _.wrap(Backbone.Model.prototype.get, function reactiveGet(bbGet, attr) { | |
if (Tracker.active) establishModelDependency(this, Tracker.currentComputation.__backboneContext || this, attr); | |
return bbGet.apply(this, Array.prototype.slice.call(arguments, 1)); | |
}); | |
Backbone.Model.prototype.toJSON = _.wrap(Backbone.Model.prototype.toJSON, function reactiveToJSON(bbToJSON) { | |
if (Tracker.active) establishModelDependency(this, Tracker.currentComputation.__backboneContext || this); | |
return bbToJSON.apply(this, Array.prototype.slice.call(arguments, 1)); | |
}); | |
// Underscore methods that are implemented on the Model. | |
var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit']; | |
_(modelMethods).each(function(method) { | |
Backbone.Model.prototype[method] = _.wrap(Backbone.Model.prototype[method], function(bbMethod) { | |
if (Tracker.active) establishModelDependency(this, Tracker.currentComputation.__backboneContext || this); | |
return bbMethod.apply(this, Array.prototype.slice.call(arguments, 1)); | |
}); | |
}); | |
// These accessor functions all rely on `get()`, so any dependencies will be established by `get()`. | |
// Backbone.Model.prototype.escape | |
// Backbone.Model.prototype.has | |
// .isValid() will trigger recomputation as expected if your .validate() function doesn't bypass the accessor functions that establish dependencies for you. | |
// Backbone.Model.prototype.isValid | |
// Backbone.Model.prototype.isNew | |
// // Wrap all Backbone.Collection accessor functions to establish dependencies on any active computations. | |
// var establishCollectionDependency = function(collection, listener, events) { | |
// if (!collection.__dependencies) collection.__dependencies = []; | |
// var dependency = new Tracker.Dependency(); | |
// var depChanged = function() { | |
// dependency.changed(); | |
// }; | |
// listener.listenTo(collection, events, depChanged); | |
// dependency.depend(); | |
// Tracker.currentComputation.onInvalidate(function() { | |
// listener.stopListening(collection, events, depChanged); | |
// }); | |
// }; | |
// Backbone.Collection.prototype.toJSON = _.wrap(Backbone.Collection.prototype.toJSON, function(bbToJSON) { | |
// if (Tracker.active) establishCollectionDependency(this, Tracker.currentComputation.__backboneContext || this, 'add change remove reset'); | |
// return bbToJSON.apply(this, Array.prototype.slice.call(arguments, 1)); | |
// }); | |
// // Underscore methods that are implemented on the Collection. | |
// var collectionMethods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', | |
// 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', | |
// 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', | |
// 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest', | |
// 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle', | |
// 'lastIndexOf', 'isEmpty', 'chain', 'sample']; | |
// _(collectionMethods).each(function(method) { | |
// Backbone.Collection.prototype[method] = _.wrap(Backbone.Collection.prototype[method], function(bbMethod) { | |
// if (Tracker.active) establishCollectionDependency(this, Tracker.currentComputation.__backboneContext || this, 'add remove reset'); | |
// }) | |
// }) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment