Details about the scope and data binding in the AngularJS framework of JavaScript, angularjsjavascript

Source: Internet
Author: User
Tags ibm developerworks

Details about the scope and data binding in the AngularJS framework of JavaScript, angularjsjavascript

AngularJS Introduction
AngularJS is an open-source front-end MVC script framework initiated by Google. It is suitable for both common WEB applications and SPA (single page applications, all user operations are completed on one page ). Unlike the positioning of Dojo in the same MVC Framework, AngularJS is more lightweight in functionality. Compared with jQuery, AngularJS saves you a lot of mechanical binding work. AngularJS is a good choice for non-enterprise WEB applications that require high development speed and no rich functional modules. AngularJS's data binding mechanism is the most complex and powerful part. This mechanism helps us to focus more on Data Model Establishment and transmission, instead of performing low-level operations on the underlying DOM.

AngularJS Scope
In jQuery-based traditional WEB applications, to listen to user input and other behaviors, you need to set a listening method for each DOM element, that is, to listen to various events on the DOM, then jQuery responds and displays it on the page. This method is simple and intuitive, but once WEB applications become large and complex, the listening code is very mechanical and redundant. what's even more terrible is that if the DOM event listening is not well managed, it is easy to expose browser resources.
AngularJS uses a series of commands to replace jQuery's event binding code. In order to organize the coordination between various commands without data confusion, AngularJS extended the concept of scope on the model layer to work with controllers to display the visual layers.
Scope)
In AngularJS, the scope is an object pointing to the application model. It is the execution environment of expressions. The scope has a hierarchical structure, which is almost the same as the corresponding DOM. The scope can monitor expressions and pass events.
In HTML code, once an ng-app instruction is defined, a scope is generated. The scope generated by ng-app is special, it is a root Scope ($ rootScope), which is the top layer of all other $ scopes.
Listing 1. Generating the root Scope

In addition to using the ng-app command to generate a scope, other commands such as ng-controller and ng-repeat will generate one or more scopes. In addition, you can create a scope by using the factory method of scope creation provided by AngularJS. These scopes all have their own inheritance context, and the root scope is $ rootScope.
After a scope is generated, when AngularJS code is compiled, the $ scope object represents the data entity of this scope. We can define various data types in $ scope, you can directly access this variable in HTML using {variable name}. The Code is as follows:
List 2. Simple data binding

<script>angular.module('app', []) .controller("ctrl", function ($scope) { $scope.btns = { ibm : 'ibm' }; });</script>

This is the simplest data binding method in AngularJS and the most widely used data binding method.
Inherited Scope)
AngularJS searches the context when creating a scope. If there is already a scope in the context, then the newly created scope will inherit the attributes and methods of its parent scope using the JavaScript prototype Inheritance Mechanism (the exception is the isolated scope, which will be discussed below ).
Some AngularJS commands will create new sub-scopes and perform prototype inheritance: ng-repeat, ng-include, ng-switch, ng-view, ng-controller, use scope: true and transclude: true: the created ve.
The following HTML defines three scopes: The $ rootScope, parentCtrl, and childCtrl sub-scopes created by the ng-app command, the scope generated by childCtrl is the sub-scope of parentCtrl.
Listing 3. inherited instances of the Scope

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

The inheritance scope complies with the prototype Inheritance Mechanism of JavaScript. This means that if we access an attribute defined in the parent scope in the subscope, JavaScript will first look for this attribute in the subscope, if the parent scope of the prototype chain is not found, the parent scope of the prototype chain will be searched again. In AngularJS, $ rootScope is at the top of the scope prototype chain, and AnguarJS will find $ rootScope. If it still cannot be found, undefined will be returned.
We use the instance code to describe this mechanism. First, we will discuss the scope Inheritance Mechanism for the prototype:
Listing 4. Scope inheritance instance-original 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 and we will get the following results:
Figure 1. Page running result.

This result is very understandable. Although no specific args attribute is defined in childCtrl, the scope of childCtrl inherits from the scope of parentCtrl. Therefore, angularJS finds the args attribute in the parent scope and sets it to the input box. In addition, if we change the content in the first input box, the content will be synchronized to the second input box:
Figure 2. modify the content of the first input box and then run the page

What happens if we modify the content of the second input box? The answer is that the content in the second input box will no longer be synchronized with the content in the first input box. When changing the content of the second input box, AngularJS will generate an args Original Type attribute for childCtrl because the model in the HTML code is explicitly bound to the scope of childCtrl. In this way, according to the AngularJS scope inheritance prototype mechanism, childCtrl finds the args attribute in its own scope, and will no longer look for The args attribute of parentCtrl. Since then, the attributes bound to the content of the two input boxes are already two different instances, so they will not be synchronized.
Figure 3. modify the content of the second input box and then run the page

If we modify the code as follows and combine the above two scenarios, let's think about what will happen?
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 that the content of any input box is always synchronized.
According to AngularJS's prototype Inheritance mechanism, if ng-model is bound to an object data, AngularJS will not create an args object for childCtrl, nor will it naturally have the args. content attribute. In this way, the args. content attribute will never exist in the scope of childCtrl and can only be searched from the parent scope. That is, the changes in the two input boxes are only changing the args. content attribute in the scope of parentCtrl. Therefore, the contents of the two are always synchronized.
Let's look at another example. Please analyze the results by yourself this time.
Listing 6. Scope inheritance instance-no longer accessing data objects in 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 content in the two input boxes will never be synchronized.
Isolate Scope)
The isolated scope is a very special scope in AngularJS, which only appears in direve ve. In the definition of directive, we add the last scope: {} attribute to create an isolation scope for this directive.
Listing 7. directive creates an isolated Scope

angular.module('isolate', []).directive("isolate", function () { return { scope : {}, };})

The biggest feature of an isolated scope is that it does not inherit its parent scope from the prototype and maintains a relatively independent external parent scope. Therefore, if you want to access the attributes of the parent scope in AngularJS ctictive that defines an isolated scope, the value is undefined. The Code is as follows:
Listing 8. Isolation of isolated 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>

In the above Code, a scope is created by declaring the scope attribute in direve ve, and its parent scope is the scope of ctrl. However, this scope is isolated, so it cannot access any attribute in the parent scope. The advantage of this design mechanism is that you can create reusable direve ve columns, which do not produce crosstalk or side effects on each other's attribute values.
AngularJS Data Binding in an isolated Scope
In the inheritance scope, we can select the sub-scope to directly operate the data in the parent scope to implement the communication between the parent and child scopes. In the isolated scope, subscopes cannot directly access and modify attributes and values of parent scopes. AngularJS provides three methods to break the restriction of isolated scopes to allow communication between isolated scopes.
One-way binding (@ or @ attr)
This is the simplest data communication between AngularJS isolated scopes and external parent scopes. The bound object can only be a string value in the parent scope and is a one-way read-only reference, the string value in the parent scope cannot be modified. In addition, the string must be declared as attr in the HTML node of the parent scope.
When using this binding method, you must explicitly specify the HTML string attribute in the parent scope in the scope attribute of directive; otherwise, an exception is 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>

After a simple analysis, the above Code declares in directive that scope: {isolates: '@'} gives direve ve the value of the HTML attribute data-isolates in the parent scope, this value is assigned to 'ibm 'in the Controller ctrl '. Therefore, the code execution result is that there are two buttons on the page named IBM.
We also noticed that isolates has been modified in the link function, but it will not be reflected in the running result. This is because isolates is always bound to the btns string in the parent scope. If the btns in the parent scope does not change, any modification to isolates in the isolated scope will not work.
Reference binding (& or & attr)
In this form of binding, the isolated scope will have the ability to access function objects in the parent scope, so as to be able to execute functions in the parent scope to obtain certain results. This method is the same as binding a document. You can only access the parent function in read-only mode, and the definition of this function must be written on the attr (attribute) node in the HTML of the parent scope.
Although this binding method cannot modify the function objects set by attr in the parent scope, it can execute the function to change the values of some attributes in the parent scope to achieve some expected results. 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>

In this example, the browser console will output a piece of "IBM DeveloperWorks" text.
In the code above, a function object $ scope. func is specified in the parent scope. In the isolated scope, func is referenced by binding HTML attributes. Note the usage of the func object in the link function, $ scope. isolates only obtains the function object, rather than calling this object. Therefore, we need to finish calling $ scope. isolates then calls this function to get the real execution result.
Bidirectional binding (= OR = attr)
Bidirectional binding gives AngularJS the most free bidirectional data communication between the isolated scope and the outside world. In bidirectional binding mode, an isolated scope can directly read and write attributes and data in the parent scope. Similar to data binding in the two isolated scopes, two-way binding must also set attribute nodes in the HTML of the parent scope to bind.
Bidirectional binding is very suitable for scenarios where sub-ctictive needs to frequently interact with the parent scope and data is complex. However, because the attributes and objects in the parent scope can be read and written freely, you need to be careful when multiple ctive ve share the data in the parent scope, which can easily cause data confusion.
The sample code is as follows:
Listing 11. Bidirectional 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 result of the code above is that three buttons appear on the browser page. The first button is titled "DeveloperWorks", and the second and third buttons are titled "IBM ".
$ Scope. btns. ibm is a lower-case "ibm". Through bidirectional binding, the IBM of the parent scope is rewritten to an upper-case "IBM" in an isolated scope and takes effect directly. The value of the parent scope is changed.

Summary
AngularJS's Lightweight Framework and its clear MVC features make it popular after its launch, and it is easy to get started in practice. What AngularJS is hard to grasp and understand is its scope and binding mechanism. This article mainly analyzes and discusses the scope and binding mechanism, and hopes that readers can understand and master this content.

Articles you may be interested in:
  • In-depth study of the two-way Data Binding Mechanism in AngularJS
  • AngularJS single-choice and multi-choice boxes implement bidirectional dynamic binding
  • Understanding Angular Data two-way binding
  • Two-way binding between custom Angular commands and jQuery-implemented Bootstrap-style data single-choice and multi-choice drop-down boxes
  • About how to implement bidirectional binding in angular. js $ watch $ digest $ apply
  • Angularjs learning notes-two-way Data Binding
  • Example of one-way binding using NG-BIND COMMANDS IN ANGULARJS
  • Instance analysis: bidirectional data binding in AngularJS framework

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.