aboutsummaryrefslogtreecommitdiffstats
path: root/src/Scope.js
diff options
context:
space:
mode:
authorMisko Hevery2011-08-12 14:32:25 -0700
committerIgor Minar2011-08-14 21:32:15 -0700
commit34f174066f1aa70dba0f97942580082169348200 (patch)
tree98dc485ab2963109689bc6fef89cf7123690b4e6 /src/Scope.js
parent530dc412c4d4700268e52920e6114f7941171706 (diff)
downloadangular.js-34f174066f1aa70dba0f97942580082169348200.tar.bz2
refactor(scope): non-recursive $digest method
Diffstat (limited to 'src/Scope.js')
-rw-r--r--src/Scope.js87
1 files changed, 47 insertions, 40 deletions
diff --git a/src/Scope.js b/src/Scope.js
index 244bd7c4..b50d6273 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -317,60 +317,67 @@ Scope.prototype = {
expect(scope.counter).toEqual(1);
</pre>
*
- * @returns {number} number of {@link angular.scope.$watch listeners} which fired.
- *
*/
$digest: function() {
- var child,
- watch, value, last,
- watchers = this.$$watchers,
- asyncQueue = this.$$asyncQueue,
- length, count = 0,
- dirtyCount, ttl = 100,
- recheck = !this.$parent || !this.$parent.$$phase;
+ var watch, value, last, next,
+ watchers,
+ asyncQueue,
+ length,
+ dirty, ttl = 100,
+ scope;
if (this.$$phase) {
throw Error(this.$$phase + ' already in progress');
}
- this.$$phase = '$digest';
do {
- while(asyncQueue.length) {
- try {
- this.$eval(asyncQueue.shift());
- } catch (e) {
- this.$service('$exceptionHandler')(e);
- }
- }
- dirtyCount = 0;
- if (watchers) {
- // process our watches
- length = watchers.length;
- while (length--) {
+
+ dirty = false;
+ scope = this;
+ do {
+ scope.$$phase = '$digest';
+ asyncQueue = scope.$$asyncQueue;
+ while(asyncQueue.length) {
try {
- watch = watchers[length];
- // Most common watches are on primitives, in which case we can short
- // circuit it with === operator, only when === fails do we use .equals
- if ((value = watch.get(this)) !== (last = watch.last) && !equals(value, last)) {
- dirtyCount++;
- watch.fn(this, watch.last = copy(value), last);
- }
+ scope.$eval(asyncQueue.shift());
} catch (e) {
- this.$service('$exceptionHandler')(e);
+ scope.$service('$exceptionHandler')(e);
}
}
- }
- child = this.$$childHead;
- while(child) {
- dirtyCount += child.$digest();
- child = child.$$nextSibling;
- }
- count += dirtyCount;
+ if (watchers = scope.$$watchers) {
+ // process our watches
+ length = watchers.length;
+ while (length--) {
+ try {
+ watch = watchers[length];
+ // Most common watches are on primitives, in which case we can short
+ // circuit it with === operator, only when === fails do we use .equals
+ if ((value = watch.get(scope)) !== (last = watch.last) && !equals(value, last)) {
+ dirty = true;
+ watch.fn(scope, watch.last = copy(value), last);
+ }
+ } catch (e) {
+ scope.$service('$exceptionHandler')(e);
+ }
+ }
+ }
+
+
+ scope.$$phase = null;
+ // find the next scope in traversal.
+ if (!(next = scope.$$childHead || scope.$$nextSibling) && scope !== this) {
+ do {
+ scope = scope.$parent;
+ if (scope == this || (next = scope.$$nextSibling)) {
+ break;
+ }
+ } while (scope !== this);
+ }
+ } while (scope = next);
+
if(!(ttl--)) {
throw Error('100 $digest() iterations reached. Aborting!');
}
- } while (recheck && dirtyCount);
- this.$$phase = null;
- return count;
+ } while (dirty);
},
/**