Explain the scope of JavaScript in the ANGULARJS framework and data binding _ANGULARJS

Source: Internet
Author: User
Tags event listener inheritance ibm developerworks

ANGULARJS Introduction
Angularjs is an open source front-end MVC scripting framework launched by Google that is suitable for both common WEB applications and SPA (single page applications, all user actions are done on one page). Unlike Dojo, where the MVC framework is positioned, Angularjs is lighter in functionality, and it saves you a lot of mechanical binding work compared to JQUERY,ANGULARJS. Angularjs is a great choice for non-enterprise WEB applications where the requirements for development speed are high and functional modules do not need to be too rich. The most complex and powerful part of ANGULARJS is its data binding mechanism, which helps us focus more on the modeling and delivery of data rather than low-level operations on the underlying DOM.

Angularjs Scopes
in traditional jquery WEB applications, in order to listen to user input and so on, you need to set a listener method for each DOM element, which is to listen for various events occurring on the DOM, then respond to it and show it on the page. This approach is simple and intuitive, but once WEB applications become large and complex, the listening code appears to be very mechanical and redundant, and, even worse, the disclosure of browser resources can easily occur if the DOM event listener is not managed properly.
In response to the problems exposed above, Angularjs uses a series of instructions instead of JQuery's event-binding code. In order to organize the coordination between various instructions without data chaos, angularjs the concept of scope in the model layer, in order to cooperate with the Controller to realize the display work of the view layer.
Scope (SCOPE)
in Angularjs, a scope is an object that points to an application model, which is the execution environment for an expression. Scopes have hierarchies, and this level is almost the same as the corresponding DOM. Scopes can monitor expressions and pass events.
In HTML code, once a ng-app instruction is defined, a scope is generated and the scope generated by Ng-app is special, a root scope ($rootScope), which is the topmost layer of all other $scope.
Listing 1. Generating the root scope

 
 

In addition to using NG-APP directives to produce a scope, other directives such as ng-controller,ng-repeat will produce one or more scopes. In addition, you can create a scope by ANGULARJS the scope-creating factory method provided by the. Each of these scopes has its own inheritance context, and the root scope is $rootscope.
After generating a scope, when writing Angularjs code, $scope object represents the data entity of this scope, we can define various data types within $scope, then we can get HTML access to this variable directly in HTML by {{variable name}}. The code is as follows:
Listing 2. Simple Data binding

<script>
angular.module (' app ', [])
 . Controller ("Ctrl", function ($scope) {
 $scope. Btns = {
 IBM: ' IBM '
 };
</script>
 
 

This is the simplest method of data binding in Angularjs, and it is also the most widely used method of data binding.
Inherit scope (inherited scope)
Angularjs When a scope is created, the context is retrieved, and if a scope already exists in the context, the newly created scope inherits the properties and methods of its parent scope with the JavaScript prototype inheritance mechanism (an exception is the orphaned scope, discussed below).
Some ANGULARJS directives create new child scopes and perform prototype inheritance: Ng-repeat, Ng-include, Ng-switch, Ng-view, Ng-controller, with Scope:true and transclude: The directive created by true.
The following HTML defines three scopes, which are child scopes created by the $rootscope,parentctrl and Childctrl created by the Ng-app directive, where Childctrl the generated scope is the child scope of the Parentctrl.
Listing 3. Inheriting instances of scopes

<body data-ng-app= "App" >
 <div data-ng-controller= "Parentctrl" >
<input data-ng-model= "args" >
<div data-ng-controller= "Childctrl" >
 <input data-ng-model= "args" >
</div>
 </div>
</body>

Inheriting scopes conforms to JavaScript's prototype inheritance mechanism, which means that if we access a property defined in a parent scope in a child scope, JavaScript first looks for the attribute in the child scope and finds it again from the parent scope on the prototype chain. If you haven't found it again, look for the parent scope of the upper-level prototype chain. In Angularjs, the top of the scope prototype chain is that $ROOTSCOPE,ANGUARJS will find the $rootscope, and if it is still not found, it will return undefined.
We use the example code to illustrate this mechanism. First, we explore the scope inheritance mechanism for prototype data types:
Listing 4. Scope Inheritance Instance-Raw type data inheritance

<script type= "Text/javascript" >
 angular.module (' app ', [])
 . Controller (' Parentctrl ', [' $scope ', function ($scope) {
 $scope. args = ' IBM DeveloperWorks ';
 }])
 . Controller (' Childctrl ', [' $scope ', function ($scope) { 
 }]);
</script>
<body data-ng-app= "app" >
 <div data-ng-controller= "Parentctrl" >
 < Input data-ng-model= "args" >
<div data-ng-controller= "Childctrl" >
 <input data-ng-model= "args" ">
</div>
 </div>
</body>

Run the page, we get the following results:
Figure 1. The results of the page run.

The result is very well understood, although no specific args attribute is defined in Childctrl, but because the scope of the Childctrl inherits from the Parentctrl scope, Angularjs finds the Args attribute in the parent scope and sets it to the input box. Also, if we change the content in the first input box, the content will react synchronously to the second input box:
Figure 2. Change the contents of the first input box after the page runs results

What happens when we modify the contents of the second input box? The answer is that the contents of the second input box will no longer be synchronized with the contents of the first input box. When the contents of the second input box are changed, because model in the HTML code is explicitly bound to the scope of the Childctrl, Angularjs generates a args original type attribute for Childctrl. Thus, according to the ANGULARJS scope to inherit the prototype mechanism, Childctrl finds the args attribute in its scope, and thus no longer looks for the args attribute of Parentctrl. From this point on, the contents of the two input boxes are bound to two different instances, so no more synchronization is maintained.
Figure 3. Change the contents of the second input box after the page runs results

If we make the following changes to the code, combined with the above two scenarios, think about how the results will occur?
Listing 5. Scope Inheritance Instance-Object data inheritance

<script type= "Text/javascript" >
angular.module (' app ', [])
 . Controller (' Parentctrl ', [' $scope ', function ($scope) {
 $scope. args = {};
 $scope. args.content = ' IBM DeveloperWorks ';
}])
. Controller (' Childctrl ', [' $scope ', function ($scope) { 
}]);
</script>
<body data-ng-app= "app" >
 <div data-ng-controller= "Parentctrl" >
 < Input data-ng-model= "args.content" >
 <div data-ng-controller= "Childctrl" >
 <input Data-ng-model= "Args.content" >
 </div>
 </div>
</body>

The answer is to change the contents of any one input box, and the contents of both are always synchronized.
According to Angularjs's prototype inheritance mechanism, if Ng-model is bound to an object data, then Angularjs will not create a args object for Childctrl, and naturally there will be no args.content attribute. In this way, the Args.content property will never exist in the Childctrl scope, only to be found from the parent scope, and that is, the change in the two input boxes is only changing the Args.content attribute in the Parentctrl scope. As a result, the contents of both are always kept synchronized.
Let's look at one more example and ask the reader to analyze the results on their own.
Listing 6-Scope inheritance instance-no longer accesses the data object of the parent scope.

<script type= "Text/javascript" >
 angular.module (' app ', [])
 . Controller (' Parentctrl ', [' $scope ', function ($scope) {
 $scope. args = {};
 $scope. args.content = ' IBM DeveloperWorks ';
}])
. Controller (' Childctrl ', [' $scope ', function ($scope) {
 $scope. args = {}; 
 $scope. args.content = ' IBM DeveloperWorks ';
}]);
</script>
<body data-ng-app= "app" >
 <div data-ng-controller= "Parentctrl" >
 < Input data-ng-model= "args.content" >
 <div data-ng-controller= "Childctrl" >
 <input Data-ng-model= "Args.content" >
 </div>
 </div>
</body>

The answer is that the contents of two input boxes will never be synchronized.
Orphaned scopes (isolate scope)
an orphaned scope is a very special scope in Angularjs, and it only appears in directive. In the definition of directive, we add the previous scope:{} property and create an isolation scope for this directive.
Listing 7. Directive creates an orphaned scope

Angular.module (' Isolate ', []). Directive ("Isolate", function () {return
 {
 scope: {},
 };
})

The most important feature of an orphaned scope is that it does not inherit its parent scope and remains relatively independent of the external parent scope. Therefore, if you want to access the properties of its parent scope in the ANGULARJS directive that defines the orphaned scope, the resulting value is undefined. The code is as follows:
Listing 8. Isolation of orphaned scopes

<script type= "Text/javascript" >
 angular.module (' app ', [])
 . Controller (' Ctrl ', [' $scope ', function ($ Scope) {
 $scope. args = {};
 }])
 . Directive ("Isolatedirective", function () {return
 {
 scope: {},
 link:function ($scope, $element, $attr) {
 Console.log ($scope. $args);//output undefined
 }
 }
; </script>
<body data-ng-app= "app" >
 <div data-ng-controller= "Ctrl" >
 <div data-isolate-directive></div>
 </div>
</body>

The above code creates a scope by declaring the scope property in directive, whose parent scope is the scope of the CTRL control. However, this scope is isolated, so it does not access any of the properties in the parent scope. The advantage of having such a design mechanism is that it is possible to create some column reusable directive that do not generate crosstalk on the property values that they have, nor do they have any side effects.
ANGULARJS Data binding for orphaned scopes
in an inheritance scope, we can select a child scope to manipulate the parent-scoped data directly to implement the communication of a parent-child scope, and in an orphaned scope, A child scope cannot directly access and modify the properties and values of a parent scope. In order to enable isolated scopes to communicate with the outside world, ANGULARJS provides three ways to break the "orphan" limit of orphaned scopes.
One-way binding (@ or @attr)
This is the simplest of angularjs orphaned scopes and outside parent scopes, the binding object can only be a string value in the parent scope, and is a one-way read-only reference, A string value in the parent scope cannot be modified, and this string must also be declared in the attr (property) of the parent scope's HTML node. When you use this binding method, you need to explicitly specify in the scope property of the directive the HTML string property referencing the parent scope, otherwise the exception will be thrown. The sample code is as follows:
listing 9. One-way binding example

 <script> angular.module (' Isolatescope ', []). Directive ("Isolatedirective", function () {return {replace:true, Template: ' <button>{{isolates}}</button> ', scope: {isolates: ' @
 ',}, Link:function ($scope, $element, $attr) {$scope. isolates = "DeveloperWorks";
 }
 };
 }. Controller ("Ctrl", function ($scope) {$scope. btns = ' IBM ';
}); </script> <body data-ng-app= "Isolatescope" > <div data-ng-controller= "Ctrl" > <button>{{btns}
}</button> <div data-isolate-directive data-isolates= "{{btns}}" ></div> </div> </body> 

Simply parse the code above, by declaring in directive that scope:{isolates: ' @ '} makes directive have the value that the HTML attribute in the parent scope data-isolates, which is assigned in the controller CTRL Value is ' IBM '. So, the result of the code running is that there are two buttons named IBM on the page.
We also note that the isolates has been modified in the link function, but will not eventually be reflected in the results of the operation. This is because isolates is always bound to the Btns string in the parent scope, and if the btns in the parent scope does not change, the isolates does not work in the orphaned scope regardless of how it is modified.
Reference binding (& or &attr)
through this form of binding, an orphaned scope will have the ability to access a function object in the parent scope, enabling functions in the parent scope to obtain some results. The binding in this way, like a one-way binding, can only access the parent function in a read-only manner, and the definition of this function must be written on the attr (attribute) node in the parent scope HTML.
This method of binding cannot modify the function object set by the attr of the parent scope, but it can achieve some expected effect by executing the function to change the value of some properties in the parent scope. The sample code is as follows:
listing 10. Reference Binding Example

 <script> angular.module (' Isolatescope ', []). Directive ("Isolatedirective",
 function () {return {replace:true, scope: {isolates: ' & ',}, Link:function ($scope, $element, $attr) {
 var func = $scope. isolates ();
 Func ();
 }
 };
 }. Controller ("Ctrl", function ($scope) {$scope. Func = function () {Console.log ("IBM DeveloperWorks");
}
 }); </script> <body data-ng-app= "Isolatescope" > <div data-ng-controller= "Ctrl" > <div Data-isolate-directive data-isolates= "func" ></div> </div> </body> 

This example, the browser's console will output a section of "IBM DeveloperWorks" text.
In the code above we specified a function object $scope.func in the parent scope, and the Func is referenced in the orphaned scope by binding the HTML property. Note that the use of the Func object in the link function is $scope. Isolates gets only the function object, not the object, so we need to call the function after the $scope.isolates is called to get the actual execution result. The
bidirectional binding (= or =attr)
bidirectional binding gives Angularjs the most free two-way data communication capability between orphaned scopes and the outside world. In bidirectional binding mode, orphaned scopes can directly read and write properties and data in the parent scope. As with the two orphaned scopes that define data binding, bidirectional binding must also be set in the parent scope's HTML to bind the attribute node.
Bi-directional binding is very useful for some child directive situations that require frequent data interaction with the parent scope, and where the data is more complex. However, because of the freedom to read and write properties and objects in the parent scope, it is easy to use caution in scenarios where multiple directive share the parent scope data, which can easily cause confusion on the data. The
sample code is as follows:
listing 11. Two-Way binding example

<script>
 angular.module (' Isolatescope ', [])
 . Directive ("Isolatedirective", function () {return
 {
 replace:true,
 Template: ' <button>{{isolates}}</button> ',
 scope: {
 isolates: ' = ',
 },
 link:function ($scope, $element, $attr) {
 $scope. ISOLATES.IBM = "IBM";
 }
 ;}
 )
 . Controller ("Ctrl", function ($scope) {
 $scope. Btns = {
 IBM: ' IBM ',
 DW: ' DeveloperWorks '
 } 
 ;
</script>
<body data-ng-app= "Isolatescope" >
 <div data-ng-controller= "Ctrl" >
 <button>{{btns.dw}}</button>
 <button>{{btns.ibm}}</button>
 <div Data-isolate-directive data-isolates= "Btns" ></div>
 </div>
</body>

The above code runs with the result that three buttons appear on the browser page, with the first button titled "DeveloperWorks" and the second and third buttons titled "IBM".
Initially, the $SCOPE.BTNS.IBM in the parent scope is lowercase "IBM", which, through bidirectional binding, overwrites IBM of the parent scope into uppercase "IBM" and takes effect directly, and the value of the parent scope is changed.

Summary
The lightweight nature of the ANGULARJS framework and its clear MVC features make it popular after launch, and it's easy to get started in practice. Angularjs more difficult to grasp and understand is its scope and binding mechanism, this article focuses on the scope and binding mechanism of the analysis and discussion, I hope that readers can understand and master this piece of content.

Related Article

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.