Original address: Http://code.angularjs.org/1.0.2/docs/guide/scope
I. What is SCOPE?
Scope (http://code.angularjs.org/1.0.2/docs/api/ng. $rootScope. Scope) is an object that points to the application model. It is also the execution context of expression (http://www.cnblogs.com/lcllao/archive/2012/09/16/2687162.html). Scope is placed in a hierarchy of DOM structures similar to the application. Scope can monitor (watch, $watch) expression and propagate events.
Ii. Characteristics of scope
- Scope provides the $watch API (http://code.angularjs.org/1.0.2/docs/api/ng. $rootScope. scope# $watch) for monitoring model changes.
- Scope provides the $apply API (http://code.angularjs.org/1.0.2/docs/api/ng. $rootScope. scope# $apply), in the "Angular realm" (Controller, server, angular event handler), propagates any model changes from the system to the view.
- Scope can be embedded into a standalone application component when it provides access to the shared model property. Scope passes (prototypes), inheriting properties from the parent scope.
- Scope provides the context when expression evaluates. For example, the {{username}} expression is meaningless unless it is evaluated with a specific scope that defines the "username" property.
Iii. Scope as Data-model (scope as data model)
Scope is the link between the application controller and the view. At the stage of the template linking (http://www.cnblogs.com/lcllao/archive/2012/09/04/2669802.html), Directive (http://www.cnblogs.com/ lcllao/archive/2012/09/09/2677190.html) Set the $watch expression in scope. $watch let directive know about the change in properties, so that directive renders the updated value into the DOM.
Both controller and directive have references to scopes, but none (references) between them (Both controllers and directives has reference to the scope, but not to EAC h other). This arrangement separates the Controller from the directive and DOM. This is an important place because it allows the controller to be isolated from view, greatly enhancing the testability of the application (greatly improves the testing story of the applications).
<! DOCTYPE html>
In the example above, we can notice that Mycontroller assigns a value to the username attribute in scope with "My Little Dada". Then, scope notifies input to be assigned, and the value of username is pre-populated into input. This shows how the controller can write data to the scope.
Similarly, a controller can attach a behavior to a scope, just as the SayHello method triggers when the user taps the Welcome button. The SayHello method can read the Username property, or you can create a greeting property. This indicates that when they are bound to an HTML input control, the properties in scope are automatically updated.
Logically, the display {{greeting}} involves the following two points:
- Retrieves the scope with the template DOM node that defines the {{greeting}} expression. In this example, the scope is the same as the scope passed to the Mycontroller. (We'll discuss the scope hierarchy later on)
- Evaluates the greeting expression through the previously retrieved scope, and then uses the result as the value of the text of the enclosing DOM element.
We can assume that scope and its own properties can be used as data for rendering views. Scope is a single source of truth about all of the view-related things (the scope is the one source-of-truth for all things View related).
In terms of testability, the separation of controller and view is commendable, as it allows us to test behavior without the interference of rendering details.
It (' Should say hello ', function () { var scopemock = {}; var cntl = new Mycontroller (scopemock); Assert that username was pre-filled expect (scopemock.username). Toequal (' World '); Assert that we read new username and greet scopemock.username = ' angular '; Scopemock.sayhello (); Expect (scopemock.greeting). Toequal (' Hello angular! ');});
Iv. Scope hierarchies (scope hierarchy)
Each angular application has only one root scope, but can have multiple child scopes.
The app can have multiple child scopes because some directive create a new child scope (refer to the directive document to see which directive can create a new scope, such as Ng-repeat). When the new scope is created, they will be added to the parent scope as a child scope. This creates a tree structure that is similar to the DOM they are attached to.
When angular evaluates {{username}}, it first looks at the Username property of the scope associated with the current element. If no corresponding attribute is found, it will search the parent scope up until the root scope is reached. In JavaScript, this behavior is referred to as "prototype inheritance", and child scope typically inherits from their parent.
This example shows the scope (what is) in the application and the stereotype inheritance of the attribute.
<! DOCTYPE html>Note that the angular automatically places the Ng-scope class into the element that is attached to the scope. <style> definition in the example above, highlight the scope of the new scope with a dashed red line. Because repeater evaluates the {{employee.name}} expression, child scope is required, but depends on which scope the expression evaluates, and different scopes have different results. Similarly, the value of {{department}} is inherited from the root scope, and only in that place has the definition of the Department attribute.
V. Retrieving Scopes from the DOM (retrieving scope from DOM)
Scope is appended as a $scope data attribute to the DOM and can be used for retrieval purposes as debugging. (It is not possible to retrieve the scope in this way in the app.) The location of the root scope attached to the DOM is defined by the location of the Ng-app directive. Usually Ng-app is placed in the
View Scope in debugger:
1. In the browser, right-click on the element of interest and select "View Element". We can see that the browser debugger highlighted the elements we selected.
2. Debugger allows us to access the currently selected element in the console using the $ variable.
3. To view the associated scope, we can enter: Angular.element ($) in the console. Scope ()
Vi. Scope Events Propagation (scope event propagation)
Scope can propagate events in a manner similar to DOM events. Events can be broadcast (http://code.angularjs.org/1.0.2/docs/api/ng. $rootScope. scope# $broadcast) to child Scope or emit (http ://code.angularjs.org/1.0.2/docs/api/ng. $rootScope. scope# $emit) into the parent Scope. (The current scope will also be executed if there is a listener)
<! DOCTYPE html>Vii. Scope life cycle (Scope lifecycle)
In the normal browser event stream, when the browser receives an event, it executes a corresponding JavaScript callback. Once the callback function finishes executing, the browser redraws the DOM and returns to the status of the wait event.
This means that angular is unaware of the change in the model when the browser executes the angular in the context of the JavaScript code. To properly handle the modification of the model, this command must be done by bringing the $apply method into the angular execution environment. Only the model changes in the $apply method are correctly angular counted. For example, a directive listens for DOM events, such as Ng-click, which must evaluate an expression in the $apply method.
After evaluating the expression, the $apply method executes a $digest. In the $digest phase, scope checks all $watch listening expressions, comparing the current value to the old value. The dirty check (dirty checking) is asynchronous. This means that an assignment statement (such as $scope.username= "angular") will not immediately cause a $watch to be notified, but $watch notification will be deferred to the $digest phase. This delay is necessary because it unites multiple model updates into a $WATCH notification, which ensures that no other $watch are executing during the $WATCH notification. If a $watch changes the value of the model, it will force an additional $digest period.
1) Creation (create Scope)
Root scope is created by $injector (Http://code.angularjs.org/1.0.2/docs/api/AUTO. $injector) during application startup. In the process of template linking, some directive will create a new child scope.
2) Watcher registration (registered watcher)
During the template linking process, Directive registers the $watch in scope. These watch will be used as a value for propagating the model to the DOM.
3) Model mutation (model change)
In order for the changes to be detected correctly, we need to wrap them in the scope. $apply. (The angular API has implicitly done this, so there is no need for additional $apply calls when doing synchronous work in the controller or doing asynchronous work with $http or $timeout).
4) Mutation observation (change monitoring)
At the end of $apply, angular will perform a $digest cycle at root scope, which will be propagated to all child scopes. In the $digest cycle, all expressions or function registered with $watch are checked to determine if the model has changed, and if the change occurs, the corresponding $watch listener will be called.
5) Scope destruction (Scope destruction)
When child scope is no longer necessary, the creator of the child scope is responsible for the scope. $destroy () API to destroy them (child scope). This will stop $digest propagation of the call propagation into child scope, allowing the memory used by the child scope model to be reclaimed by GC (garbage collector).
1. Scopes and Directives
During the compilation phase, compiler relies on the DOM template to match the directive. Directive can usually be divided into two main categories:
- Observer Directive (observing directives), such as the dobule-curly expression {expression}}, registers the listener with the $watch method. Whenever the expression (value) changes, such directive must be notified to update the view.
- Listener-type directive (Listener directive), such as Ng-click, registers a listener into the DOM. When the DOM listener is triggered, directive executes the relevant expression and updates the view by using the $apply method.
When an external event (such as a user action, timer, or xhr) is monitored, the associated expression must be applied to the scope through the $apply method, allowing all listeners to update correctly.
2. directives that Create Scopes
In most cases, directive and scope are mutually influential, but new scope instances are not created. However, some directive (such as Ng-controller and Ng-repeat) create a new scope, attaching the child scope to the corresponding DOM element. We view the scope of any DOM element by using Angular.element (adomelement). Scope ().
3. Controllers and Scopes
In the following cases, scope and controller are mutually affected:
- The controller uses scope to expose the Controller method to the template (view Ng-controller (Http://code.angularjs.org/1.0.2/docs/api/ng.directive:ngController)).
- The controller defines the method (behavior), which can change the model (the property on scope).
- The controller may register watch in the model. These watch will be executed immediately after the controller behavior is executed.
4. Scope $watch Performance Considerations (Scope $watch Performance considerations)
In angular, a dirty detection of scope (Dirty checking) is a common operation in order to detect changes in properties. For this reason, this requires the dirty checking function to be efficient. Be careful dirty the checking function does not do any DOM access, because DOM accesses several orders of magnitude slower than accessing JavaScript object properties.
Angularjs Learning Note--scope