Scope
(type in module ng
)
A root scope can be retrieved using the $rootScope
key from the
$injector
. Child scopes are created using the
$new()
method. (Most scopes are created automatically when
compiled HTML template is executed.)
Here is a simple scope snippet to show how you can interact with the scope.
angular.injector(['ng']).invoke(function($rootScope) { var scope = $rootScope.$new(); scope.salutation = 'Hello'; scope.name = 'World'; expect(scope.greeting).toEqual(undefined); scope.$watch('name', function() { scope.greeting = scope.salutation + ' ' + scope.name + '!'; }); // initialize the watch expect(scope.greeting).toEqual(undefined); scope.name = 'Misko'; // still old value, since watches have not been called yet expect(scope.greeting).toEqual(undefined); scope.$digest(); // fire all the watches expect(scope.greeting).toEqual('Hello Misko!'); });
A scope can inherit from a parent scope, as in this example:
var parent = $rootScope; var child = parent.$new(); parent.salutation = "Hello"; child.name = "World"; expect(child.salutation).toEqual('Hello'); child.salutation = "Welcome"; expect(child.salutation).toEqual('Welcome'); expect(parent.salutation).toEqual('Hello');
Scope([providers][, instanceCache]);
providers(optional) – {Object.<string, function()>=} –
Map of service factory which need to be provided for the current scope. Defaults to ng.
instanceCache(optional) – {Object.<string, *>=} –
Provides pre-instantiated services which should
append/override services provided by providers
. This is handy when unit-testing and having
the need to override a default service.
{Object}
– Newly created scope.
$apply()
is used to execute an expression in angular from outside of the angular framework.
(For example from browser DOM events, setTimeout, XHR or third party libraries).
Because we are calling into the angular framework we need to perform proper scope life-cycle
of exception handling
,
executing watches
.
$apply()
function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } }
Scope's $apply()
method transitions through the following stages:
$eval()
method.$exceptionHandler
service.watch
listeners are fired immediately after the expression
was executed using the $digest()
method.exp(optional) – {(string|function())=} –
An angular expression to be executed.
string
: execute using the rules as defined in expression.function(scope)
: execute the function with current scope
parameter.{*}
– The result of evaluating the expression.
Dispatches an event name
downwards to all child scopes (and their children) notifying the
registered ng.$rootScope.Scope#$on
listeners.
The event life cycle starts at the scope on which $broadcast
was called. All
listeners
listening for name
event on this scope get notified.
Afterwards, the event propagates to all direct and indirect scopes of the current scope and
calls all registered listeners along the way. The event cannot be canceled.
Any exception emmited from the listeners
will be passed
onto the $exceptionHandler
service.
name – {string} –
Event name to emit.
args – {...*} –
Optional set of arguments which will be passed onto the event listeners.
{Object}
– Event object, see ng.$rootScope.Scope#$on
Removes the current scope (and all of its children) from the parent scope. Removal implies
that calls to $digest()
will no longer
propagate to the current scope and its children. Removal also implies that the current
scope is eligible for garbage collection.
The $destroy()
is usually used by directives such as
ngRepeat
for managing the
unrolling of the loop.
Just before a scope is destroyed a $destroy
event is broadcasted on this scope.
Application code can register a $destroy
event handler that will give it chance to
perform any necessary cleanup.
Process all of the watchers
of the current scope and its children.
Because a watcher
's listener can change the model, the
$digest()
keeps calling the watchers
until no more listeners are
firing. This means that it is possible to get into an infinite loop. This function will throw
'Maximum iteration limit exceeded.'
if the number of iterations exceeds 10.
Usually you don't call $digest()
directly in
controllers
or in
directives
.
Instead a call to $apply()
(typically from within a
directives
) will force a $digest()
.
If you want to be notified whenever $digest()
is called,
you can register a watchExpression
function with $watch()
with no listener
.
You may have a need to call $digest()
from within unit-tests, to simulate the scope
life-cycle.
var scope = ...; scope.name = 'misko'; scope.counter = 0; expect(scope.counter).toEqual(0); scope.$watch('name', function(newValue, oldValue) { scope.counter = scope.counter + 1; }); expect(scope.counter).toEqual(0); scope.$digest(); // no variable change expect(scope.counter).toEqual(0); scope.name = 'adam'; scope.$digest(); expect(scope.counter).toEqual(1);
Dispatches an event name
upwards through the scope hierarchy notifying the
registered ng.$rootScope.Scope#$on
listeners.
The event life cycle starts at the scope on which $emit
was called. All
listeners
listening for name
event on this scope get notified.
Afterwards, the event traverses upwards toward the root scope and calls all registered
listeners along the way. The event will stop propagating if one of the listeners cancels it.
Any exception emmited from the listeners
will be passed
onto the $exceptionHandler
service.
name – {string} –
Event name to emit.
args – {...*} –
Optional set of arguments which will be passed onto the event listeners.
{Object}
– Event object, see ng.$rootScope.Scope#$on
Executes the expression
on the current scope returning the result. Any exceptions in the
expression are propagated (uncaught). This is useful when evaluating Angular expressions.
var scope = ng.$rootScope.Scope(); scope.a = 1; scope.b = 2; expect(scope.$eval('a+b')).toEqual(3); expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
expression(optional) – {(string|function())=} –
An angular expression to be executed.
string
: execute using the rules as defined in expression.function(scope)
: execute the function with the current scope
parameter.{*}
– The result of evaluating the expression.
Executes the expression on the current scope at a later point in time.
The $evalAsync
makes no guarantees as to when the expression
will be executed, only that:
$digest cycle
will be performed after
expression
execution.Any exceptions from the execution of the expression are forwarded to the
$exceptionHandler
service.
expression(optional) – {(string|function())=} –
An angular expression to be executed.
string
: execute using the rules as defined in expression.function(scope)
: execute the function with the current scope
parameter.Creates a new child scope
.
The parent scope will propagate the $digest()
and
$digest()
events. The scope can be removed from the scope
hierarchy using $destroy()
.
$destroy()
must be called on a scope when it is desired for
the scope and its child scopes to be permanently detached from the parent and thus stop
participating in model change detection and listener notification by invoking.
isolate – {boolean} –
if true then the scope does not prototypically inherit from the parent scope. The scope is isolated, as it can not see parent scope properties. When creating widgets it is useful for the widget to not accidentally read parent state.
{Object}
– The newly created child scope.
Listens on events of a given type. See $emit
for discussion of
event life cycle.
name – {string} –
Event name to listen on.
listener – {function(event)} –
Function to call when the event is emitted.
{function()}
– Returns a deregistration function for this listener.
The event listener function format is: function(event, args...)
. The event
object
passed into the listener has the following attributes:
targetScope
- {Scope}
: the scope on which the event was $emit
-ed or $broadcast
-ed.currentScope
- {Scope}
: the current scope which is handling the event.name
- {string}
: Name of the event.stopPropagation
- {function=}
: calling stopPropagation
function will cancel further event
propagation (available only for events that were $emit
-ed).preventDefault
- {function}
: calling preventDefault
sets defaultPrevented
flag to true.defaultPrevented
- {boolean}
: true if preventDefault
was called.Registers a listener
callback to be executed whenever the watchExpression
changes.
watchExpression
is called on every call to $digest()
and
should return the value which will be watched. (Since $digest()
reruns when it detects changes the watchExpression
can execute multiple times per
$digest()
and should be idempotent.)listener
is called only when the value from the current watchExpression
and the
previous call to watchExpression
are not equal (with the exception of the initial run,
see below). The inequality is determined according to
angular.equals
function. To save the value of the object for later comparison, the
angular.copy
function is used. It also means that watching complex options will
have adverse memory and performance implications.listener
may change the model, which may trigger other listener
s to fire. This
is achieved by rerunning the watchers until no changes are detected. The rerun iteration
limit is 10 to prevent an infinite loop deadlock.If you want to be notified whenever $digest
is called,
you can register a watchExpression
function with no listener
. (Since watchExpression
can execute multiple times per $digest
cycle when a change is
detected, be prepared for multiple calls to your listener.)
After a watcher is registered with the scope, the listener
fn is called asynchronously
(via $evalAsync
) to initialize the
watcher. In rare cases, this is undesirable because the listener is called when the result
of watchExpression
didn't change. To detect this scenario within the listener
fn, you
can compare the newVal
and oldVal
. If these two values are identical (===
) then the
listener was called due to initialization.
// let's assume that scope was dependency injected as the $rootScope var scope = $rootScope; scope.name = 'misko'; scope.counter = 0; expect(scope.counter).toEqual(0); scope.$watch('name', function(newValue, oldValue) { scope.counter = scope.counter + 1; }); expect(scope.counter).toEqual(0); scope.$digest(); // no variable change expect(scope.counter).toEqual(0); scope.name = 'adam'; scope.$digest(); expect(scope.counter).toEqual(1);
watchExpression – {(function()|string)} –
Expression that is evaluated on each
$digest
cycle. A change in the return value triggers a
call to the listener
.
string
: Evaluated as expressionfunction(scope)
: called with current scope
as a parameter.listener(optional) – {(function()|string)=} –
Callback called whenever the return value of
the watchExpression
changes.
string
: Evaluated as expressionfunction(newValue, oldValue, scope)
: called with current and previous values as parameters.objectEquality(optional) – {boolean=} –
Compare object for equality rather than for reference.
{function()}
– Returns a deregistration function for this listener.
{number}
– Unique scope ID (monotonically increasing alphanumeric sequence) useful for debugging.
Broadcasted when a scope and its children are being destroyed.