What’s the $scope?
description
Transcript of What’s the $scope?
@nickheiner | github.com/nickheiner
What’s the $scope?
Part II | 3 June 2013
@nickheiner | github.com/nickheiner
2
Agenda1. Overview
How to watch; how watching is implemented
Scope hierarchy2.Advanced Use Cases
Events$apply, $eval, $destroy
3.Best Practices & Tricks
@nickheiner | github.com/nickheiner
Opower today
The Company• Serving 85 utilities in 6
countries• Over 2TWh saved to date• 40% of US household data
under management totaling 100 billion reads
• 300 people in Washington, San Francisco, London, Singapore• Forbes #10 of 100 Most
Promising Companies
A SaaS Customer Engagement Platform
@nickheiner | github.com/nickheiner
4
@nickheiner | github.com/nickheiner
Controllers &
Directives
$scope points to your data model
$scope
View(angular
templates)
read write
@nickheiner | github.com/nickheiner
Scope in the view
@nickheiner | github.com/nickheiner
Scope in the view
@nickheiner | github.com/nickheiner
Scope in the view
@nickheiner | github.com/nickheiner
$watch
» Watch expression will be called many times, so it should be fast / idempotent
» Making the watch expression slow in one of the few ways to really screw yourself in angular
@nickheiner | github.com/nickheiner
$watch expressions
» You’re not limited to just naming variables» Parsed and evaluated with parse.js» Eval demo
@nickheiner | github.com/nickheiner
$watch expressions
» Third arg specifies referential or deep equality» fiddle
@nickheiner | github.com/nickheiner
$watch expressions
» Use an empty watch expression as a wildcard
@nickheiner | github.com/nickheiner
$watch expressions
» Coming soon: $watchCollection
@nickheiner | github.com/nickheiner
Fire watcher
s
Done!
Watch / digest cycle
JS event (user input, http
response, etc) yes
No
Did anythin
g change
?
@nickheiner | github.com/nickheiner
Dirty checking v. change listeners» Less NSFW than it sounds» Excellent SO answer from Misko» Angular uses dirty checking; Knockout and Backbone use
change listeners» Dirty checking requires more comparisons, so the
comparisons must be fast
@nickheiner | github.com/nickheiner
Dirty checking v. change listeners» Less NSFW than it sounds» Excellent SO answer from Misko» Angular uses dirty checking; Knockout and Backbone use
change listeners» Dirty checking requires more comparisons, so the
comparisons must be fast
Problem with change listeners Solution in angular landMust use inheritance instead of POJOs
Use POJOs!
Excessive change events fired Minimal change events firedMany change listeners may be in progress at once
Only one change listener may be in progress at once
@nickheiner | github.com/nickheiner
POJOs
Backbone
Angular
@nickheiner | github.com/nickheiner
Excessive Changes fired
» O(numTweets) change events fired with change listeners
» O(1) change events fired with dirty checking
@nickheiner | github.com/nickheiner
Simultaneous change listeners
» Both handlers will be in progress at once with change listening
» Only one handler will fire at a time with dirty checking
@nickheiner | github.com/nickheiner
Watch / digest cycle example
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn false false
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn undefined undefined0 auth.loggedInCo
untundefined undefined
$id expression old val new val0 auth.loggedIn false false0 auth.loggedInCount 0 0
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn false false0 auth.loggedInCount 0 01 mostRecentServerUpdate null null
auth.loggedIn
auth.loggedInCount
mostRecentServerUpdate
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn false false0 auth.loggedInCount 0 01 mostRecentServerUpdate null null
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn false true0 auth.loggedInCount 0 01 mostRecentServerUpdate null null
» Digest iteration count: 0
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn true true0 auth.loggedInCount 0 11 mostRecentServerUpdate null null
» Digest iteration count: 1
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn true true0 auth.loggedInCount 1 11 mostRecentServerUpdate null null
» Digest iteration count: 2
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn true true0 auth.loggedInCount 1 11 mostRecentServerUpdate null null
» Digest iteration count: Done!
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn true true0 auth.loggedInCount 1 11 mostRecentServerUpdate null 1370273731
» Digest iteration count: 0
@nickheiner | github.com/nickheiner
Watch / digest cycle example$id expression old val new val0 auth.loggedIn true true0 auth.loggedInCount 1 11 mostRecentServerUpdate 1370273731 1370273731
» Digest iteration count: 1
@nickheiner | github.com/nickheiner
$scopes are arranged in a hierarchy
@nickheiner | github.com/nickheiner
$scopes are arranged in a hierarchy
$rootScope
trending-tweets ng-repeat-0 ng-repeat-n…
tweet tweet
Linked list
@nickheiner | github.com/nickheiner
$scopes are arranged in a hierarchy
Main
Content
Subsection
Inheritance works with controller scopes, too.
@nickheiner | github.com/nickheiner
Prototypes$rootScope
top-tweets
Child scopes prototypically inherit from their parents
@nickheiner | github.com/nickheiner
Prototypes$rootScope
top-tweets
Child scopes prototypically inherit from their parentsunless the child is an isolate scope
@nickheiner | github.com/nickheiner
Prototypes $rootScope
trending-tweets
Transcluded scopes inherit from their parents
Transcluded and isolated scopes are siblings
ng-transclude
@nickheiner | github.com/nickheiner
Prototypes
@nickheiner | github.com/nickheiner
Scopes and directives
@nickheiner | github.com/nickheiner
Scopes and directives
@nickheiner | github.com/nickheiner
Scopes and directives
@nickheiner | github.com/nickheiner
41
Agenda1. Overview
How to watch; how watching is implemented
Scope hierarchy2.Advanced Use Cases
Events$apply, $eval, $destroy
3.Best Practices & Tricks
@nickheiner | github.com/nickheiner
Firing a watch/digest yourself
» Want to start a cycle on scope change» Angular gives you this for free
» $timeout v. setTimeout» $http» $q» Controllers, directives, etc
» Start it manually to integrate with non-angular code
@nickheiner | github.com/nickheiner
Firing a watch/digest yourself
Fire watcher
s
Done!
JS event (user input, http
response, etc) yes
No
Did anythin
g change
?
@nickheiner | github.com/nickheiner
Firing a watch/digest yourself
Fire watcher
s
Done!
JS event (user input, http
response, etc) yes
No
Did anythin
g change
?
$rootScope.$apply()
@nickheiner | github.com/nickheiner
Firing a watch/digest yourself
@nickheiner | github.com/nickheiner
Events!
$rootScope
ng-repeat-0
tweet
@nickheiner | github.com/nickheiner
Events!
$rootScope
ng-repeat-0
tweet
@nickheiner | github.com/nickheiner
Events!
$rootScope
ng-repeat-0
tweet
@nickheiner | github.com/nickheiner
$eval
» Manually evaluate an expression against the scope
@nickheiner | github.com/nickheiner
$destroy
» Removing a DOM node doesn’t remove the associated scope» Do it yourself with $destroy» Broadcasts a $destroy event» Fiddle» ng-repeat calls $destroy:
@nickheiner | github.com/nickheiner
Deregister
» $watch returns a deregistration function
@nickheiner | github.com/nickheiner
52
Agenda1. Overview
How to watch; how watching is implemented
Scope hierarchy2.Advanced Use Cases
Events$apply, $eval, $destroy
3.Best Practices & Tricks
@nickheiner | github.com/nickheiner
Only put objects on the scope
» Good
» Bad
Misko: “Scope isn’t your model; scope points to your model.
More detailed discussion
@nickheiner | github.com/nickheiner
Use $rootScope for sharing state» Good
» Bad
@nickheiner | github.com/nickheiner
Be careful with $scope.$parent.$parent
» Use $rootScope or events instead
@nickheiner | github.com/nickheiner
Debug with angular.element().scope()
@nickheiner | github.com/nickheiner
Questions?
Scope source code
@nickheiner | github.com/nickheiner
We’re Hiring! (Shameless Plug)» Come be part of a company that’s saving the world one line of
code at a time!• JavaScript Engineer – Web• Senior Software Engineer• Front End Developer/Designer• And many many more: Opower.com/careers
» Why Work at Opower?• You’ll be challenged by some of the smartest people you’ve ever
met to do your best and have fun doing it!• Feel free to ask me anything about working at Opower