# `Scope` (type in module `ng` )

Improve this doc

## Description

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.

          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!');

### Inheritance

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');

## Usage

    Scope([providers][, instanceCache]);

### Parameters

- `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.

### Returns

`{Object}` –

Newly created scope.

## Methods

- ### $apply(exp)

  `$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`.

  ##### Life cycle

  #### Pseudo-Code of `$apply()`

                 function $apply(expr) {
                   try {
                     return $eval(expr);
                   } catch (e) {
                     $exceptionHandler(e);
                   } finally {
                     $root.$digest();
                   }
                 }

  Scope's `$apply()` method transitions through the following stages:

  1. The expression is executed using the `$eval()` method.
  2. Any exceptions from the execution of the expression are forwarded to the `$exceptionHandler` service.
  3. The `watch` listeners are fired immediately after the expression was executed using the `$digest()` method.

  #### Parameters

  - `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.

  #### Returns

  `{*}` –

  The result of evaluating the expression.

- ### $broadcast(name, args)

  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 emitted from the `listeners` will be passed onto the `$exceptionHandler` service.

  #### Parameters

  - `name – {string} –`

    Event name to emit.

  - `args – {...*} –`

    Optional set of arguments which will be passed onto the event listeners.

  #### Returns

  `{Object}` –

  Event object, see `ng.$rootScope.Scope#$on`

- ### $destroy()

  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.

- ### $digest()

  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.

  #### Example

                 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);

- ### $emit(name, args)

  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.

  #### Parameters

  - `name – {string} –`

    Event name to emit.

  - `args – {...*} –`

    Optional set of arguments which will be passed onto the event listeners.

  #### Returns

  `{Object}` –

  Event object, see `ng.$rootScope.Scope#$on`

- ### $eval(expression)

  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.

  #### Example

                 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);

  #### Parameters

  - `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.

  #### Returns

  `{*}` –

  The result of evaluating the expression.

- ### $evalAsync(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:

  - it will execute in the current script execution context (before any DOM rendering).
  - at least one `$digest cycle` will be performed after `expression` execution.

  Any exceptions from the execution of the expression are forwarded to the `$exceptionHandler` service.

  #### Parameters

  - `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.

- ### $new(isolate)

  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.

  #### Parameters

  - `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.

  #### Returns

  `{Object}` –

  The newly created child scope.

- ### $on(name, listener)

  Listens on events of a given type. See `$emit` for discussion of event life cycle.

  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.

  #### Parameters

  - `name – {string} –`

    Event name to listen on.

  - `listener – {function(event, args...)} –`

    Function to call when the event is emitted.

  #### Returns

  `{function()}` –

  Returns a deregistration function for this listener.

- ### $watch(watchExpression, listener, objectEquality)

  Registers a `listener` callback to be executed whenever the `watchExpression` changes.

  - The `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.)
  - The `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.
  - The watch `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.

  #### Example

                 // 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);

  #### Parameters

  - `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 expression
    - `function(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 expression
    - `function(newValue, oldValue, scope)`: called with current and previous values as parameters.
  - `objectEquality(optional) – {boolean=} –`

    Compare object for equality rather than for reference.

  #### Returns

  `{function()}` –

  Returns a deregistration function for this listener.

- ### $watchCollection(obj, listener)

  Shallow watches the properties of an object and fires whenever any of the properties change (for arrays this implies watching the array items, for object maps this implies watching the properties). If a change is detected the `listener` callback is fired.

  - The `obj` collection is observed via standard $watch operation and is examined on every call to $digest() to see if any items have been added, removed, or moved.
  - The `listener` is called whenever anything within the `obj` has changed. Examples include adding new items into the object or array, removing and moving items around.

  #### Example

                $scope.names = ['igor', 'matias', 'misko', 'james'];
                $scope.dataCount = 4;

                $scope.$watchCollection('names', function(newNames, oldNames) {
                  $scope.dataCount = newNames.length;
                });

                expect($scope.dataCount).toEqual(4);
                $scope.$digest();

                //still at 4 ... no changes
                expect($scope.dataCount).toEqual(4);

                $scope.names.pop();
                $scope.$digest();

                //now there's been a change
                expect($scope.dataCount).toEqual(3);

  #### Parameters

  - `obj – {string|Function(scope)} –`

    Evaluated as expression. The expression value should evaluate to an object or an array which is observed on each `$digest` cycle. Any shallow change within the collection will trigger a call to the `listener`.

  - `listener – {function(newCollection, oldCollection, scope)} –`

    a callback function that is fired with both the `newCollection` and `oldCollection` as parameters. The `newCollection` object is the newly modified data obtained from the `obj` expression and the `oldCollection` object is a copy of the former collection data. The `scope` refers to the current scope.

  #### Returns

  `{function()}` –

  Returns a de-registration function for this listener. When the de-registration function is executed then the internal watch operation is terminated.

## Properties

- ### $id

  #### Returns

  `{number}` –

  Unique scope ID (monotonically increasing alphanumeric sequence) useful for debugging.

## Events

- ### $destroy

  Broadcasted when a scope and its children are being destroyed.

  #### Type:

  broadcast

  #### Target:

  scope being destroyed