build_your_own_angularjs_sample
build_your_own_angularjs_sample
build_your_own_angularjs_sample
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Build Your Own Angular Chapter 1. Scopes And Digest<br />
Scope.prototype.$digest = function() {<br />
var ttl = 10;<br />
var dirty;<br />
this.$$lastDirtyWatch = null;<br />
do {<br />
while (this.$$asyncQueue.length) {<br />
var asyncTask = this.$$asyncQueue.shift();<br />
asyncTask.scope.$eval(asyncTask.expression);<br />
}<br />
dirty = this.$$digestOnce();<br />
if ((dirty || this.$$asyncQueue.length) && !(ttl--)) {<br />
throw "10 digest iterations reached";<br />
}<br />
} while (dirty || this.$$asyncQueue.length);<br />
};<br />
Now we can be sure the digest will terminate, regardless of whether it’s running because<br />
it’s dirty or because there’s something in its async queue.<br />
Scope Phases<br />
Another thing $evalAsync does is to schedule a $digest if one isn’t already ongoing. That<br />
means, whenever you call $evalAsync you can be sure the function you’re deferring will be<br />
invoked “very soon” instead of waiting for something else to trigger a digest.<br />
For this to work there needs to be some way for $evalAsync to check whether a $digest<br />
is already ongoing, because in that case it won’t bother scheduling one. For this purpose,<br />
Angular scopes implement something called a phase, which is simply a string attribute in<br />
the scope that stores information about what’s currently going on.<br />
As a unit test, let’s make an expectation about a field called $$phase, which should be<br />
“$digest” during a digest, “$apply” during an apply function invocation, and null otherwise:<br />
test/scope_spec.js<br />
it("has a $$phase field whose value is the current digest phase", function() {<br />
scope.aValue = [1, 2, 3];<br />
scope.phaseInWatchFunction = undefined;<br />
scope.phaseInListenerFunction = undefined;<br />
scope.phaseInApplyFunction = undefined;<br />
scope.$watch(<br />
function(scope) {<br />
scope.phaseInWatchFunction = scope.$$phase;<br />
return scope.aValue;<br />
},<br />
function(newValue, oldValue, scope) {<br />
32 ©2014 Tero Parviainen Errata / Submit