Skip to content

Instantly share code, notes, and snippets.

@barnash
Created May 3, 2014 07:44
Show Gist options
  • Save barnash/0084be83e96ac449d950 to your computer and use it in GitHub Desktop.
Save barnash/0084be83e96ac449d950 to your computer and use it in GitHub Desktop.
Code from angular - digest loop presentation
function Scope() {
this.$$watchers = [];
this.$$lastDirtyWatch = null;
}
Scope.prototype.$$areEqual = function(newValue, oldValue, valueEq) {
if (valueEq) {
return _.isEqual(newValue, oldValue);
} else {
return newValue === oldValue ||
(typeof newValue === 'number' && typeof oldValue === 'number' &&
isNaN(newValue) && isNaN(oldValue));
}
};
Scope.prototype.$watch = function(watchFn, listenerFn, valueEq) {
var self = this;
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() {},
valueEq: !!valueEq
};
self.$$watchers.push(watcher);
return function() {
var index = self.$$watchers.indexOf(watcher);
if (index >= 0) {
self.$$watchers.splice(index, 1);
}
}
};
Scope.prototype.$$digestOnce = function() {
var self = this;
var dirty = false;
this.$$watchers.every(function(watch) {
var newValue = watch.watchFn(self);
var oldValue = watch.last;
if (!self.$$areEqual(newValue, oldValue, watch.valueEq)) {
watch.last = (watch.valueEq ? _.cloneDeep(newValue) : newValue);
watch.listenerFn(newValue, oldValue, self);
dirty = true;
self.$$lastDirtyWatch = watch;
} else if (self.$$lastDirtyWatch === watch) {
return false;
}
return true;
});
Scope.prototype.$digest = function() {
var ttl = 10;
var dirty;
this.$$lastDirtyWatch = null;
do {
dirty = this.$$digestOnce();
if (dirty && !(ttl--)) {
throw "10 digest iterations reached";
}
} while (dirty);
};
Scope.prototype.$eval = function(expr, locals) {
return expr(this, locals);
};
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr);
} finally {
this.$digest();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment