Skip to content

Instantly share code, notes, and snippets.

@vamp
Last active August 29, 2015 13:57
Show Gist options
  • Save vamp/9637933 to your computer and use it in GitHub Desktop.
Save vamp/9637933 to your computer and use it in GitHub Desktop.
/**
* Transform for Knockout 3+
* (c) Denis Gulin
* License: MIT (http://www.opensource.org/licenses/mit-license.php)
*/
!function (factory) {
// Support three module loading scenarios
if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
// [1] CommonJS or Node: hard-coded dependency on "knockout"
factory(require("knockout"));
} else if (typeof define === 'function' && define['amd']) {
// [2] AMD anonymous module with hard-coded dependency on "knockout"
define(["knockout"], factory);
} else {
// [3] No module loader (plain <script> tag) - use the global `ko` object
factory((this || (0, eval)("this"))["ko"]);
}
}(function (ko) {
/**
* @param {Array} observables
* @param {Function} evaluator
* @param {ko.observable|ko.observableArray|?} observable
* @returns {ko.subscribable}
*/
ko.transform = function(observables, evaluator, observable){
if (!observable){
observable = ko.observable();
}
// Arguments for evaluator.
var values = [],
// last value (do not use peek)
lastValue,
// Routine for observable update.
update = function(){
if (lastValue !== (lastValue = evaluator.apply(null, values))){
observable(lastValue);
}
},
// List of subscriptions.
subscriptions = ko.utils.arrayMap(observables, function(one, i){
values[i] = one.peek();
return one.subscribe(function(value){
values[i] = value;
update();
});
});
// Perform initial notification.
update();
// Override dispose.
observable.dispose = (function(dispose){
return function(){
dispose && dispose();
ko.utils.arrayForEach(subscriptions, function(one){
one.dispose();
});
};
})(observable.dispose);
// Return created observable.
return observable;
};
/**
* Shortcut for single observable.
* @param {Function} evaluator
* @returns {*|ko.subscribable}
*/
ko.subscribable.fn.transform = function(evaluator){
return ko.transform([this], evaluator);
};
return ko;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment