Upload
eric-greene
View
287
Download
7
Embed Size (px)
Citation preview
Full Stack Toronto
AngularJS
$scope and $digest Loop
Deep Dive
Topics to Cover
l$scope relationships
l$digest & $apply
l$watches & $observes
$scope – two parent-child relationships
lPrototype inheritance
lChild scopes can isolated or prototypally inherit from its parent
scope in the hierarchy
lHierarchy
l$parent property to reference the parent
lChild Nodes are organized in a linked list instead of an array for
performance reason because they are frequently created and
destroyed and array modification routines are more expensive than
updating references in a linked list
l$childHead – first child
l$childTail – last child
$scope – two parent-child relationships
lHierarchy (continued)
lSiblings
l$nextSibling
l$prevSibling
lCode Demo
lPrototype Inheritance
l$scope Hierarchy
Why prototype inheritance?
lAll of functionality needed for a $scope is attached to the
$rootScope, and made available via prototype inheritance to all
non-isolated child $scopeslNote: isolation refers to prototype inheritance, not the linked heirarchy
of $scopes
lPrototype inheritance is preferred over a closure because it is
more efficient and uses less memory
Isolated $scope
lNormally, scopes will prototypally inherit from their parent in the
hierarchy
lHowever, isolated scopes can be created that have a $parent
reference, but they do not inherit prototypally from their parent or
any other scopelSome people think an isolated $scope inherits from the $rootScope,
this is not true
lCode demo to examine child scope which are and are not
isolated
When to isolate and when not to isolate...
lIn AngularJS,lScopes created by ng-controller always prototypally inherit
lScopes created using $new will prototypally inherit unless true is
passed inlPrimarily, used when assigning a $scope to transcluded content
lScopes created by directives can prototypally inherit or be
isolatedlAlways prefer an isolated scope for maximum directive reusability
$digest Loop
lChild $scope traversallDepth first, starting from the $scope object from which it is called
lDoes not traverse up from the $scope object from which it is called
lPrototypal inheritance (isolated scopes) does not impact the $digest
loop traversal processlIt follows the linked hierarchy of the scopes not the prototypal inheritance
hierarchy
lCode Demo
$digest Loop TTL
lWhenever a value on the $scope is changed during the $digest
loop, it causes the $digest loop to execute againlThe $digest loop will trigger itself up to 10 (by default) times before it
stops and throws an error to prevent an infinite loop
lIf you need to increase this value, you can do so in a config function,
by passing in the $rootScopeProvider and calling digestTtl function
and passing in the new TTL valuelNote – only increase this value if you really know what you are doing as it can
adversely impact the performance and user experience of your AngularJS
application
lCode Demo
$apply
lProvides a try/catch/finally structure to properly handle errorslReview AngularJS Source Code
lDemo Try/Catch/Finally
lPasses the function argument to the $eval function on the
$scope from which $apply is calledlCan be called without passing a function to simply safely call the
$digest function
lAfter executing $eval, $digest on the $rootScope is called
$$postDigest & $timeout
lTo execute code one time after a completed $digest cycle there
are two methodsl$$postDigest
lNot recommended, the double $ means its a private function to AngularJS
lSimply pass a function to the method and it will be executed after the $digest
loop and it will not trigger another $digest loop
lStores functions in a queue that are executed at the end of the $digest Loop
after the $digest phase has been cleared
lAdvantage – no delay between $$postDigest functions and completion of
$digest phase
$$postDigest & $timeout
l$timeoutl0 for delay and false for invokeApply
lPublic method, returns a promise
lMust be called during the $apply or $digest to queue up to execute after the
$digest loop has completed
lLimitation – because of the single threaded nature of JavaScript, it will be
queued up after the last task in the JavaScript event loop which could mean it
could possibly not be executed immediately after the $digest loop completes
$digest & $apply Summary
lSimilaritylBoth trigger the $digest loop
lDifferencesl$digest starts from the $scope on which it is called
l$apply executes the $digest from the $rootScope
lAdditionallyl$apply executes the expression on the $scope from which it is called
using $eval
l$apply provides error handling, calling $digest on the $rootScope from
a finally block
$watches and $observes
lBoth are executed during the $digest loop
l$watches can be configured in controllers, $observes cannot be
lBoth $watches and $observes can be configured in directives,
usually, within the post-link function
l$watches can only observe a property on the scope, $observes
only observe an attribute of an element on which a directive is
applied but it can observe an interpolated expression
$watches and $observes
l$watches require move overhead then $observes, as such,
$observes are preferred over $watches
l$watches require the execution of a conditional function that
checks to see if the value has changed, then it executes the
listener functionlThe conditional function must execute for each watcher; therefore, do
not place multiple watchers on the same conditional function, place on
watcher and have it handle multiple things
l$observes simply observe an interpolated attribute value, if it
changes then all of the $observe functions exectutelThis requires less overhead than a $watch
Best Practices
- Always, prefer an isolated $scope for directive to ensure loose
coupling with the surrounding $scope and directive reusability
- Use $apply instead of $digest directly unless you have a large
scope model and need to limit the number of child scopes the
$digest function is executed against
- Limit the use of $watches and $observes to UI affecting events
and when possible choose an $observe over a $watch
- Never $watch the same $scope property or function more than
once