In addition to using the NG-APP directive 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 factory method that is provided to create the scope. These scopes have their 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 in $scope, and then we can make HTML access to this variable directly in HTML with {{variable name}}. The code is as follows:
<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.
Inheritance 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 sub-scopes and prototype inheritance: Ng-repeat, Ng-include, Ng-switch, Ng-view, Ng-controller, with Scope:true and transclude: True to create the directive.
The following HTML defines three scopes, the child scopes created by the $rootscope,parentctrl and Childctrl created by the Ng-app directive, where the Childctrl generated scopes are Parentctrl sub-scopes.
Listing 3. Inherited 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>
The inheritance scope 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 that attribute in the child scope and does not find it again from the parent scope on the prototype chain, If you haven't found it, then look for the parent scope that will go up the first-level prototype chain. In AngularJS, the top of the scope prototype chain is $ROOTSCOPE,ANGUARJS will find $rootscope, and if it is not found, it will return undefined.
We use the example code to illustrate the mechanism. First, let's explore the scope inheritance mechanism for the prototype data type:
Listing 4. Scope Inheritance Instance-primitive 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>
To run the page, we get the following results:
Figure 1. The results of the page run.This result is very well understood, although the specific args attribute is not defined in Childctrl, but because the scope of Childctrl inherits from the scope of the Parentctrl, AngularJS finds the Args property 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 be synchronized to the second input box:
Figure 2. After changing the contents of the first input box, the results of the page runWhat 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 you change the contents of the second input box, because the model in the HTML code is explicitly bound to the scope of the Childctrl, AngularJS generates an args primitive type property for Childctrl. Thus, by inheriting the prototype mechanism from the AngularJS scope, Childctrl can find the args attribute in its own scope, and will no longer look for the args attribute of the Parentctrl. Since then, the contents of the two input boxes have been bound to two different instances, so no more synchronization will be maintained.
Figure 3. Page run results after changing the contents of the second input boxIf we make the following changes to the code, combined with the above two scenarios, 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 whatever changes the contents of any one of the input boxes, the contents of the two are always synchronized.
Based on the prototype inheritance mechanism of AngularJS, if Ng-model binds an object data, AngularJS will not create an args object for Childctrl and will naturally have no args.content properties. In this way, the Args.content property will never exist in the Childctrl scope, only from the parent scope, or the change in the two input boxes is only changing the Args.content property in the Parentctrl scope. Therefore, the contents of both are always synchronized.
Let's look at one more example and ask the reader to analyze the results on its own.
Listing 6. Scope inheritance Instance-no longer accesses the parent-scoped data object.<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 the two input boxes will never be synchronized.
Orphaned scopes (Isolate scope)An orphaned scope is a very special scope in AngularJS, which appears only in directive. In the definition of directive, we add the previous scope:{} property, creating an isolation scope for the directive.
Listing 7. Directive create an orphaned scopeAngular.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 outside parent's scope. Therefore, if you want to access the properties of its parent scope in AngularJS directive that defines the orphaned scope, the resulting value is undefined. The code is as follows:
Listing 8. Isolation of isolation 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.L OG ($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 to which ctrl belongs. However, this scope is orphaned, so it does not access any of the properties in the parent scope. The advantage of having such a design mechanism is the ability to create a number of directive that can be reused, and these directive do not generate crosstalk on each other's property values, nor do they have any side effects.
AngularJS data binding for orphaned scopesIn an inheritance scope, we can select child scopes to manipulate parent-scope data directly to achieve parent-child scope communication, whereas in an orphaned scope, the child scope cannot directly access and modify the properties and values of the parent scope. In order to enable isolated scopes to communicate with the outside world, AngularJS provides three ways to break the "isolate" limitation of the isolated scope.
One-way binding (@ or @attr)This is the simplest form of data communication between the AngularJS orphan scope and the outside parent scope, the bound object can only be a string value in the parent scope, and is a one-way read-only reference, unable to modify the string value in the parent scope, and the string must also be in the HTML node of the parent scope to The attr (property) is declared in a way.
When using this binding method, it is necessary to explicitly specify the HTML string attribute in the scope property of the directive reference 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, TE Mplate: ' <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>
A simple analysis of the above code, by declaring the scope:{isolates in directive: ' @ '} allows directive to have the value of the HTML attribute in the parent scope, which is assigned the value in the controller Ctrl to ' IBM '. So, the result of the code is that there are two buttons on the page called IBM.
We also noticed that isolates was modified in the link function, but would 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 will not work in the orphaned scope, regardless of how it is modified.
Reference bindings (& or &attr)With this form of binding, the orphaned scopes will have the ability to access function objects in the parent scope, enabling them to perform functions in the parent scope to obtain some results. This way of binding is like a one-way binding, which can only access the parent function in a read-only manner, and the definition of the function must be written on the attr (attribute) node in the parent-scoped HTML.
The binding of this method cannot modify the function object set by the attr of the parent scope, but it can be done by executing a function to change the values of some properties in the parent scope to achieve some desired effect. The sample code is as follows:
Listing 10. Reference Binding Example<script> angular.module (' Isolatescope ', []). Directive ("Isolatedirective", function () {return {replace:true, SC Ope: {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's console will output an "IBM DeveloperWorks" text.
In the above code, we specify a function object $scope.func in the parent scope, and the Func is referenced in the orphaned scope by binding the HTML property. It is important to note that the use of the Func object in the link function is $scope. Isolates only gets 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.
Bidirectional binding (= or =attr)Two-way binding gives AngularJS the most free bidirectional data communication function between the isolated scope and the outside world. In two-way binding mode, an orphaned scope can read and write properties and data directly from the parent scope. As with the two isolated scopes that define data binding, two-way binding must also be bound in the HTML of the parent scope to set the attribute node.
Bidirectional binding is well suited for scenarios where some sub-directive require frequent and parent scopes for data interaction, and 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, TE Mplate: ' <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 above code is 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", with two-way binding, an orphaned scope in which IBM overwrites the parent scope into uppercase "IBM" and takes effect directly, and the value of the parent scope is changed.
Original link: http://www.ibm.com/developerworks/cn/opensource/os-cn-AngularJS/index.html
AngularJS scope and data binding mechanism