Talking about the mutual communication between instruction and instruction in Angularjs

Source: Internet
Author: User

When it comes to Angularjs, the first thing we think about is the two-way data binding and instruction system, both of which are the most attractive places in Angularjs. Two-way data binding, feel nothing to say, then today we will briefly discuss the ANGULARJS framework of the command system.

Directives as the most important part of the ANGULARJS, so the framework itself has a lot of instructions, but in development, these directives often do not meet our needs, so we also need to customize some of the instructions. Then a ANGULARJS instruction can have four representations in the HTML code:

1, as a new HTML element to use.

2. Use as an attribute of an element

<div hello></div>

3, as an element of the class to use

<div class= "Hello" ></div>

4. Use as a comment

<!--Directive:hello--
Note here there is a trap, that is, in the "Directive:hello" This is a space behind, otherwise there is no effect, at the same time recommend the method of comment or less, if not to pursue the tall, then the sex bar. Since the instruction has more than four forms of expression, then how exactly does he define it?
. directive (' Hello ', function () {   return {    restrict: ' AECM ',    Template: ' <button>click Me</button > '   }  })

Above is the simplest code to define a directive, not one. In the above code, the Directive () method defines a new directive that has two parameters, the first ' hello ' is the name of the directive, and the second parameter is the function that returns the instruction object. So in the above code, the function mainly uses two attributes to define this Hello command:

1, restrict[string] This attribute, is mainly used to specify the instructions in the HTML code can use what form of expression. A represents a property, E represents an element, C represents a class, and M represents a comment. In fact, we generally use AE in both ways.

2, template[string or function] This property, specifies that the instruction is angular compiled and linked (link) generated HTML markup, this property can be simple to only one HTML text inside, can also be particularly complex, When the value of this property is function, the method returns the string representing the template, and the {{}} expression can be used inside.

Template:function () {     return ' <button>click me</button> ';}

In general, however, the template attribute is replaced by Templateurl and used to point to an external file address, so we usually put the templates in an external HTML file and use Templateurl to point to him.

In defining the directive, in addition to the above two most basic attributes, we will also use many other properties, then we will come to one by one:

1, Priority[number] attribute, this attribute is to specify the priority of the custom instruction, when a DOM element above a command, it is necessary to compare the priority of the instruction, the high priority of the instruction first execution. This priority is used in order to execute the instruction before the compile function, the first sort of, then about compile this function, we will be in the following carefully.

2, Terminal[boolean] property, which is used to define whether to stop the current element is lower than the priority of this directive, if the value is true, is normal, in the order of precedence high and low execution, if set to false, Directives that are less than the priority of this directive are not executed on the current element.

3, Replace[boolean] property, which is used to specify whether the generated HTML content will replace the HTML element that defines the directive. When we set the value of this property to True, open the console and look at the elements that this command generates:

This will be the case when we set false:

4, Link[function] attribute, in the above example, our custom instruction actually does not have much meaning, this is just one of the simplest instructions, there are a lot of attributes we have not defined for him, so there is not much use. For example, the link function, which includes three parameters: scope, Element, Attrs. This link function is primarily used to add event listeners to DOM elements, monitor model property changes, and update the DOM. It contains three parameters:

One:The scope parameter, when we do not define the scope property for the directive, then he represents the scope of the parent controller.

Two:the element parameter, which is the jqlite (subset of jquery) of the instruction, wraps the DOM elements. If you introduced jquery before introducing Angularjs, then this element is a jquery element, not a jqlite element. Since this element has been jquery/jqlite wrapped, we do not need to use $ () to package the DOM operation.

Three:the attrs parameter, which contains the normalized parameter object for the attribute of the element in which the directive is located.

5, Scope[boolean or Object] property, which is the scope of scope that defines the directive, false by default, which means that the directive inherits the scope of the parent controller, You can use the properties of the parent controller's scope at will, but it is undesirable to contaminate the attributes in the parent scope. So we can let scope take the following two values: True and {}.

When true, indicates that angular is given an instruction to create a scope that inherits from the parent scope.

varMyapp=angular.module (' MyApp '), []). Controller (' Myctrl ', [' $scope ',function($scope) {$scope. Color= ' Red '; }]). directive (' Hello ',function () {   return{restrict:' AECM ', replace:true, Template:' <button ng-click= ' SayHello () ' style= ' Background-color: {{color}} ' >click me</button> ', Scope:true, Link:function(scope,elements,attrs) {Elements.bind (' Click ',function() {elements.css (' Background-color ', ' Blue '); })    }   }  })

Here we define a color property for the parent scope, and assign a value of red, in the scope property of the Hello directive, we give true, so angular creates a scope for this directive that inherits from the parent scope, and then in the template property , we used {{}} The Color property inherited from the parent scope, so the button is red.

When {}, represents the creation of an isolated scope that does not inherit the properties of the parent scope. But there are times when we need to access attributes or methods in the parent scope, so what should we do? Angular long for us to think of this, there are three ways to let our memory above the operation:

One: using @ To implement one-way binding, if we give only the scope of this {} value, then the above code of the button's background color will be gray. , and if we need to use the color property of the parent scope, we can write this:

scope{  color:' @color '}
<color= "{{color}}"></Hello>

Here are two points to note: 1. The attribute color in scope represents the color inside the expression of the template {{}}, which must be identical. 2. The value of the attribute color in scope, that is, the color after the @, represents the attribute color in the following HTML element, so the two must also be consistent when the property name and the template expression {{}} are used in the same name, you can omit the property name after the @ , and then write the following form.

scope{  color:' @ '}

From the value of scope in the directive, it can be seen that the color in the expression {{}} in the directive template points to the color property of the current element element, and the value of the Color property is the value of the property color of the parent scope. The parent scope passes the value of his color property to the color property of the current element, and then the Color property passes the value to color in the expression in the template, which is one-way.

Two: use = to achieve two-way binding

. directive (' Hello ',function () {   return{restrict:' AECM ', replace:true, Template:' <button style= ' Background-color: {{color}} ' >click me</button> ', scope:{color:=}, Link:function(scope,elements,attrs) {Elements.bind (' Click ',function() {elements.css (' Background-color ', ' Blue '); Scope. $apply (function() {Scope.color= ' Pink '; })     })    }   }  })
<color= "Color"></Hello><  type= "text"  ng-model= "Color"/>

Here we have a two-way binding to the color property in scope of the directive and the color property in the parent scope, and to the link function of the instruction, add a click event, click the button to change the color of the button, and change the value of the color property of the instruction scope, Add an input tag to the HTML page, and output or enter the value of the parent scope's Color property. Here's a place to note: The value of the property name of the current element is not added to the expression {{}} because the parent scope passes a real scope data model instead of a simple string, so we can pass a simple string, array, Even complex objects give the scope of the instruction. Now let's see what happens when you click on this button.

Here we can see that the color of the button is changed to pink, indicating that the color property of the scope of the command has changed, resulting in a change in the colour of the button. But this is not just a button change, but note that the value in the input form becomes pink, which means that the color property of the parent scope has changed. Also, let's enter a color in input to see what happens.

, it can be seen that when we enter another color in the form, the color of the button also changes, which means that the color property of the scope of the directive has been changed. In summary we can find that the use of ' = ' to achieve a two-way binding.

Third: Use & Call the method in the parent scope

varMyapp=angular.module (' MyApp '), []). Controller (' Myctrl ', [' $scope ',function($scope) {$scope. Color= ' Red '; $scope. SayHello=function() {alert (' Hello ');  }; }]). directive (' Hello ',function () {   return{restrict:' AECM ', replace:true, Template:' <button ng-click= ' SayHello () ' style= ' Background-color: {{color}} ' >click me</button> ', scope:{color:=, SayHello:' & '}, Link:function(scope,elements,attrs) {Elements.bind (' Click ',function() {elements.css (' Background-color ', ' Blue '); Scope. $apply (function() {Scope.color= ' Pink '; })     })    }   }  })
<color= "Color"  sayhello= "SayHello ()"></  Hello><type= "text"  ng-model= " Color "/>

Here we have two places to note: 1, we need not only to use the Ng-click directive in the template, bind the method in the parent scope to invoke, but also to add a property to the current element, and this property points to the method of the parent scope to invoke. 2, the directive scope property SayHello, the current element's attribute SayHello, the template binds the event method name SayHello These three must be consistent. So then we can click on the button and pop up a dialog box.







6, Transclude[boolean] property, which allows us to specify whether an instruction can contain any content
function () {   return{    restrict:' AECM ',    replace:true,    Transclude:true,    scope:{},    Template:' <div ng-transclude></div> ',   }  })
< Hello >  <span>{color}}</span></  Hello>

When his value is true, this is the value of the output on the page. When false, the page will be blank. Here is a place to note that is <span>{{color}}</span>, where the color is the color in the parent scope. is not the color attribute of scope in the directive.

7, Compile[function] Parameters, the method has two parameters element,attrs, the first parameter element refers to the elements of the directive, the second attrs refers to the parameters given on the element of the standardized list. Here we have a place to note: The Compile function cannot access scope and must return a link function. However, if you do not set the compile function, you can configure the link function normally, (with compile, you cannot return by compile with the Link,link function).

directive (' Hello ',function () {   return{restrict:' AECM ', replace:true, Translude:true, Template:' <button ng-click= ' SayHello () ' style= ' Background-color: {{color}} ' >click me</button> ', scope:{color:=, SayHello:' & '}, compile:function(element,attrs) {return function(scope,elements,attrs) {Elements.bind (' Click ',function() {elements.css (' Background-color ', ' Blue '); Scope. $apply (function() {Scope.color= ' Pink ';    })      })     }; }   }  })

Now let's click on this button

We found that the thing that happened after clicking the button here is the same as the Link property before, which is really not very different.

In fact, in most cases, we only need to use the link function. This is because most instructions only need to consider registering event monitoring, monitoring models, and updating the DOM, all of which can be done in the link function. However, for instructions like ng-repeat, it is necessary to clone and repeat DOM elements multiple times, which is done by the compile function before the link function executes. So why do we need two separate functions to complete the build process, and why can't we just use one? To answer this question, we need to understand how instructions are compiled in angular!

8. How the instructions are compiled

When our angular application boot, angular will use the $compile service to traverse the DOM element, after all instructions are recognized, will invoke the compile method of the instruction, return a link function, and then add the link function to the later execution of the In the link function list, this process is called the compile phase. Instructions such as ng-repeat need to be cloned many times, the compile function is executed only once during the compilation phase, and these templates are copied, but the link function is executed for each replicated instance. So separate processing, let us in the performance of a certain improvement (this sentence is a bit less understanding, I was copied from other places.)

9, controller[string or function] and require[string or string[]] parameters, we need to use the controller function when we want to allow other instructions to interact with your instructions. When another instruction wants to interact, it needs to declare its reference to your command controller instance (require).

. directive (' Hello ',function () {   return{scope:{}, require:' ^he ', compile:function(element,attrs) {return function(scope,elements,attrs,cntins) {Cntins.fn ()}; }}). directive (' He ',function () {   return{restrict:' AE ', scope:{}, Controller:function($scope, $compile, $http) { This. fn=function() {alert (' Hello ');    }; }   }  })
< He > <  color= "Color"  sayhello= "SayHello ()"></Hello  ></he>

When the page has finished loading, a dialog box pops up.

Well, above is my time to learn angular, the knowledge of the instructions learned, first written here.


Talking about the mutual communication between instruction and instruction in Angularjs

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.