Angularjs Development Guide 12: Scopes

Source: Internet
Author: User
Tags emit

What is a scope?

A scope is an object that points to the application model. It is the execution environment of an expression. Scopes have hierarchies, which are almost identical to the corresponding DOM. Scopes can monitor expressions and pass events.

Scope features
    • Scopes provide APIs ($watch) to observe changes in the model.
    • The scope provides APIs ($apply) to map changes from any model from the Angularjs realm (Angular realm) through the system to the view.
    • Scopes can be nested on application components by sharing model members. A scope inherits properties from the parent scope.
    • Scopes provide the context in which an expression executes. For example, the expression {{username}} itself is meaningless unless it is placed in the scope of the specified username property. FormatDate
Scope as the data model

The scope is the "glue" between the controller and the view. At the template link stage, the directive sets the $watch expression for the scope. $watch makes the instruction aware of the change in properties, which allows the instruction to re-render and update the values in the DOM.

Both the controller and the instruction hold the scope references, but do not hold each other. This allows the controller to be detached from the instruction and DOM. This is important because it makes the controller completely unaware of the presence of the view, which greatly improves the testing of the application.

Index.html:

<!doctype html> Ng-app>  <script Src="Http://code.angularjs.org/angular-1.0.2.min.js"></script> <script Src="Script.js"></script>  <body> <div Ng-controller= "Mycontroller" > Your name: <input type= "text"  ng-model= "username"  > <button ng-click = ' SayHello () ' >greet </button>  {{greeting}} span class= "tag" ></div> </body></HTML>              

Script.js:

function Mycontroller($scope) { $scope .=  ' world ' ; $ Scope. SayHello = function ()  Span class= "pun" >{ $scope .=  ' Hello '  +< Span class= "PLN" > $scope .+  '! '  }; }             /span>                

In the example above, Mycontroller assigns the value world to the username in the scope. The scope then notifies input of the assignment, and then input is rendered to be pre-populated and worthwhile. This shows how the controller writes data to the scope.

Similarly, the controller can add behavior to the scope, as you see in the SayHello method, which is called when the user taps the ' greet ' button. This shows that when an attribute is bound to an HTML input element, it is automatically updated.

Logically, {{greeting}} the rendering of an expression requires:

    • Gets and defines the {{greeting}} scope associated with the DOM node in the template. In this case, it is the scope that is passed into the Mycontroller.
    • Calculates the value of an expression in conjunction with the scope obtained in the previous step, substituting the value in the DOM for the expression.

You can think of the scope and its properties as the data used to render the view. The scope is the unique source of the change associated with the view.

From a test point of view, the controller and the separation are the results we want, because this allows us to eliminate the interference of rendering details when testing the behavior.

It(' should say hello ', function() { VarScopemock= {}; VarCntl= New Mycontroller(Scopemock); Assert that username is pre-filledExpect(Scopemockusername). toequal ( Span class= "com" >//Assert that we read new username and Greet Scopemock.username =  ' angular ' ; Scopemock. Sayhello  Expect (scopemock greeting). toequal ( ' Hello angular! ' });             
Scope level

Every ANGULARJS application has an absolute root scope. However, there may be multiple child scopes.

An app can have more than one scope because there are directives that generate new child scopes (refer to the documentation for the directives to see which directives create new scopes). When new scopes are created, they are added to the parent scope as child scopes, which makes the scope a tree structure that is one with the corresponding DOM structure.

When Angularjs executes an expression {{username}} , it first looks for properties that are called username in the scope associated with the current node. If it is not found, it will continue to search the upper scope until the root scope. In JavaScript, this is called the inheritance of prototype types, and child scopes inherit from the parent scope in the form of prototypes.

The following example shows the scopes in the application, their inheritance.

Index.html:

<!doctype html> Ng-app>  <script Src="Http://code.angularjs.org/angular-1.0.2.min.js"></script> <script Src="Script.js"></script>  <body> <div ng-controller= "Employeecontroller" span class= "tag" >> Manager: {{employee.name}} [{{department}}]<br>< Span class= "PLN" > Reports: <ul> <li  ng-repeat= "employee in Employee.reports" > {{Employee.Name}} [{{department}}] </li> </ul>  { Greeting}} </div> </body>< span class= "tag" ></HTML>             

STYLE.CSS:

/* remove .doc-example-live in jsfiddle */.doc-example-live .ng-scope { border: 1px dashed red;}

Script.js:

function Employeecontroller($scope) {$scope.Department= ' Engineering '; $scope .= { Name: , Reports:< Span class= "PLN" > [ {name :  John Smith ' }, {name:  ' Mary Run ' } ] };               /span>                

Note that when the scope and element are associated, Angularjs automatically adds the Ng-scope class name to the corresponding element. The range of scopes in this example is highlighted. The presence of a child scope is necessary because the iterator executes an {{employee.name}} expression that generates different values depending on the scope. Similarly, {{department}} the execution is inherited from the root scope, because it is defined only in the root scope.

Getting scopes from the DOM

The scope is associated to the DOM as a data property of $scope, and can be obtained when debugging is required. The DOM that is associated with the root action (unlike those that can only be obtained within the app) is where the NG-APP directive is defined. In general, Ng-app are placed in elements, but can also be placed in other elements, for example, only

To detect scopes in the debugger:

Right-click on the element you want to view, and select "Review Element" in the menu. You should see the debugger in the browser, and the element you selected is highlighted.

The debugger lets you get the variables in the console $0 .

In the console, get the scope you want to associate:angular.element($0).scope()

Delivery of scope events

Event passing in the scope is similar to DOM event delivery. An event can be broadcast to a child scope or passed to the parent scope.

index.html:

<!doctype html> Ng-app>  <script Src="Http://code.angularjs.org/angular-1.0.2.min.js"></script> <script Src="Script.js"></script>  <body> <div Ng-controller="Eventcontroller">Root Scope<tt>MyEvent</tt>Count: {{count}}<ul> <li Ng-repeat="I in [1]" Ng-controller="Eventcontroller"> <button Ng-click="$emit (' MyEvent ')">$emit (' MyEvent ')</button> <button Ng-click="$broadcast (' MyEvent ')">$broadcast (' MyEvent ')</button> <br>Middle Scope<tt>MyEvent</tt>Count: {{count}}<ul> <li  Ng-repeat= "item in [1, 2]"  ng-controller< Span class= "pun" >= "Eventcontroller" > Leaf scope <tt>myevent</tt> count: {{count}} span class= "tag" ></li> </ul>  </li> </ul> </div>< Span class= "PLN" > </body></HTML>    

script.js:

function EventController($scope) { $scope.count = 0; $scope.$on(‘MyEvent‘, function() { $scope.count++; });}
Declaration Period for Scopes

The general workflow after the browser receives the event is to execute a corresponding JavaScript callback. Once the callback is executed, the browser will re-render the DOM and return to the status of the wait event.

When the browser calls JavaScript code outside of the ANGULARJS context, Angularjs is unaware of the changes to the model. To properly handle changes to the model, use the $apply method to enter the execution context of the ANGULARJS. Only model modifications executed within the $apply method are handled correctly by Angularjs. For example, an instruction listens to a DOM event, for example ng-click , it must execute an expression in the $apply method.

After the expression is executed, the $apply enters the $digest phase. The $digest phase scope examines all the $watch expressions and compares them to the previous values. This inspection work is performed asynchronously. This means that the assignment statement, if $scope.username="angular" it does not immediately cause $watch to be notified, will instead wait until the $digest phase is notified. This approach is justified because it consolidates updates of multiple models into a $WATCH notification and guarantees that there will be no other $watch execution during a $watch notification. If a $watch changes the value of the model, it generates an additional $digest phase.

    1. Create-The root scope is created when the app is started by $injector. In the template linking phase, some directives create new sub-scopes. 2. Observer registration-During the template link phase, the directive registers the observer on the scope. These observers are used to pass changes to the model to the DOM.
    2. Model changes-in order to properly observe model changes, you need and can only change them in scope. $apply (). (The Angularjs API will do this implicitly, so you don't need to call $apply in the controller or in the $http, $timeout, etc.).
    3. Changing observations-at the end of $apply, Angularjs executes a $digest loop in the root scope, which passes the changes to all child scopes. In the $digest loop, all $watch expressions or functions are detected to observe the changes in the model. If a change is detected, the $watch listener callback is called.
    4. Scope destruction--if the sub-scope is no longer useful. The creator of the child scope will then be responsible for destroying it with the scope. $destroy () API. This stops $digest and then calls the child scope, and allows the content occupied by the scope to be recycled.
Scopes and Directives

During the compilation phase, the compiler matches instructions in the DOM. Directives are usually divided into two types:

    • An observer-type instruction, such as a double curly brace expression {{expression}} , uses $watch to register a listener. This type of instruction is notified whenever an expression changes, and the view can be updated.
    • Listener-type directives, for example ng-click , register a listener with the DOM. When the DOM listener fires, the instruction executes the relevant expression and updates the view using the $apply method.

When an external event (such as a user action, timer, or XHR) is triggered, the corresponding expression must be called within the $apply () method for its corresponding scope so that all listeners are correctly updated.

The directives that will create scopes

In most cases, directives and scopes interact but do not produce new scope instances. However, some directives, such as ng-controller and ng-repeat will wear a new scope, and associated to the corresponding DOM element, you can use the angular.element(aDomElement).scope() method to get a certain DOM element related scope.

Controllers and Scopes

Scopes and controllers interact in the following situations:

    • The controller exposes the method through the scope to the template (reference ng-controller )
    • The method (behavior) in the controller definition that can change the model (scope properties)
    • The controller registers the observer on the model. These observers will be executed immediately after the controller behavior is executed.

Refer ng-controller to For more information.

The scope of the $watch operation to be noted

The change of the detection attribute is a common operation in Angularjs, so it should be efficient. Note that the method that performs the instrumentation should not contain any DOM operations, because DOM fetching is much slower than property fetching in JavaScript objects.

Angularjs Development Guide 12: Scopes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.