An analysis of instruction _angularjs in Angularjs

Source: Internet
Author: User
Tags event listener html page

Instruction (directives) is the most important part of all ANGULARJS applications. Although Angularjs has provided very rich instructions, it is often necessary to create application-specific directives.

When it comes to Angularjs, the first thing we think about is a 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 come to a simple discussion of the framework of the instruction system, I am also a beginner, looked up some information, if there are some bad places, Angularjs pointed out.

The directive is the most important part of the ANGULARJS, so the framework itself takes a lot of instructions, but in development, these instructions don't usually 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, as an element of the property to use

<div hello></div>

3, as an element of the class to use

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

4, as a note to use

<!--Directive:hello-->

Note that there is a trap, is in the "Directive:hello" after this to have a space, otherwise it is no effect, and recommended the method of annotation or less use, if you want to pursue tall, then the sex bar. Since the instructions have more than four forms of expression, then how does he define the specific?

. directive (' Hello ', function () {return
{
restrict: ' AECM ',
Template: ' <button>click Me</button > '
}
})

It's the simplest code to define a command, not one. In the above Code, Directive () defines a new instruction that has two parameters, the first ' hello ' is the name of the directive, and the second is the function that returns the instruction object. So in the code above, the function basically uses two properties to define this hello instruction:

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

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

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

But in general, template This property will be replaced by the Templateurl, with it to point to an external file address, so we usually put the template in an external HTML file, and then use Templateurl to point to him.

In the definition of instructions, in addition to the above two most basic attributes, we will also use many other attributes, then we will come to the next one by one:

1, Priority[number] attribute, this attribute is to specify the priority of the custom instruction, when a DOM element above has more than one instruction, it needs to compare the priority of the instruction, priority high order first execution. This priority is used to order the compile function before executing the instruction, then the compile function, we will say carefully below.

2, Terminal[boolean] property, which is used to define whether to stop instructions that are lower in the current element than the precedence of this instruction, if the value is true, that is normal, in order of precedence, and if set to false, Will not execute instructions that are less priority than the instruction on the current element.

3, Replace[boolean] property, this property is used to specify whether the generated HTML content will replace the HTML element that defines this instruction. When we set the value of this property to True, open the console and see if you can find the element that this instruction generates:

This is true when we set it to false:


4, Link[function] property, in the above example, our custom instructions do not have much meaning, this is just a simple instruction, there are many attributes we have not defined for him, so not much use. For example, the link function, which includes three parameters: scope, Element, Attrs. This link function is used primarily 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 attribute for the instruction, then he represents the scope of the parent controller.

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

Three: The Attrs parameter, which contains the normalized parameter object of the attribute of the element in which the instruction resides.

5, Scope[boolean or object property, which is used to define a scope for a directive, is false by default, meaning that the instruction inherits the scope of the parent controller, It is not advisable to use the properties of the scope of the parent controller at will, but that would contaminate the properties of the parent scope. So we can have scope take the following two values: True and {}.

When true, indicates that angular gives the instruction a scope that inherits from the parent scope.

var myapp=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 attribute for the parent scope and assign it to red, and we give true in the scope attribute of the hello instruction, so angular creates a scope that inherits from the parent scope for this instruction, and then in the template property , we use the Color property inherited from the parent scope with {{}}, so the button is red.

When {}, represents the creation of an isolated scope and does not inherit the properties of the parent scope. But sometimes we also need to access the properties or methods in the parent scope, so what should we do? Angular has already thought of this for us, and there are three ways we can remember the operation:

One: use @ To implement one-way binding, if we only give scope of this {} value, then the above Code button 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 '
}
 
 

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

scope{
color: ' @ '
}

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

Two: Use = implement bidirectional 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 ';})}}}
)
 
 

Here we bind the color attribute in the scope of the instruction to the color attribute in the parent scope, and add a click event to the command's link function, and the click button will change the button's colour and change the value of the command scope's Colors property. Add an input tag to the HTML page, output or enter the value of the color property of the parent scope. Here's one place to note: The value of the property name of the current element is not to be added to the {{}}}, because the parent scope here passes a real scope data model rather than a simple string, so we can pass a simple string, array, Even complex objects to the scope of the instruction. Now let's see what happens when you click on this button.

As we can see here, the color of the button turns to pink, which means that clicking lets the color attribute of the scope of the command change, causing the button's colors to change. But this is not just a button change, notice that the value in the input form has also become pink, which means that the color property of the parent scope has also changed. Also, let's enter a color in input to see what happens.

You can see that when we enter another color in the form, the color of the button changes, which means that the scope of the directive's color attribute is changed. In conclusion, we can find that using ' = ' is a two-way binding.

Three: Use & Invoke the method in the parent scope

var myapp=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 ';})}}}
)
 
 

Here we have two places to note: 1, we not only need to use the Ng-click directive in the template, bind the method in the parent scope to invoke, but also add a property to the current element, and this attribute points to the method of the parent scope to invoke. 2, the directive scope attribute SayHello, the current element's attribute SayHello, the template bound event method name SayHello these three to be consistent. So 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 arbitrary content

. directive (' Hello ', function () {
return{
restrict: ' AECM ',
replace:true,
transclude:true,
scope:{},
Template: ' <div ng-transclude></div> ',
}
})
 
 

When his value is true, this is the value of the output on the page. When false, the page will be blank. There is a place for attention, the <SPAN>{{COLOR}}</SPAN>, where the color is the color of the parent scope. is not the color attribute of the scope in the instruction.

7, Compile[function] parameter, this method has two parameter element,attrs, the first parameter element refers to the element where the instruction is located, and the second attrs refers to the normalized list of parameters given on the element. 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 properly (with compile, you cannot return it 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 what happened after the click of the button here is the same as the link property, which is really not very different.

In fact, in most cases, we just need to use the link function. This is because most of the instructions only need to consider registering the event listener, monitoring the model, and updating the DOM, which can be done in the link function. However, for instructions like ng-repeat, you need to clone and repeat DOM elements multiple times, which are 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 not just use one? To answer this question, we need to understand how the instructions are compiled in the angular!

8, how the instructions are compiled

When our angular application boot starts, angular will use the $compile service to traverse the DOM element, and after all the instructions are recognized, the instruction's compile method will be invoked, a link function will be returned, and the link function added to the later execution In the list of link functions, this process is called the compile phase. Instructions like ng-repeat need to be duplicated many times, the compile function is executed only once in the compile phase, and the template is copied, but the link function is executed for each instance that is replicated. So separate processing, so that we have a certain improvement in performance (this sentence is a bit less understanding, I am from another place copy come over.) The original is http://blog.jobbole.com/62249/here).

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 the controller instance of your instruction (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 ');
}}
}
)
 
 

When the page finishes loading, a dialog box pops up.

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

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.