ANGULARJS instruction Detailed

Source: Internet
Author: User
Tags addchild

I. What is an instruction?

In the Angularjs authoritative tutorial, directives can be simply understood as functions running on specific DOM elements, and I think it can also be understood to parse the custom HTML tag into the original tag and add some extended functions (functions) to it.

Ii. How does the instruction work?

The first is the compile phase, where ANGULARJS traverses the entire document and handles the instructions on the page based on the instruction definition in JavaScript. In the process of traversal, it is possible that one layer is layered, and the depth is traversed. Once the traversal and compilation is complete, a function called a template function is returned. We can modify the compiled Dom tree before this function is returned (return).

Then there is the link stage, which links the template to the scope by calling the link function in the previous step. This turns on the link function for each instruction, allowing each instruction to register the listener for the DOM and establish the scope of the listener. This finally forms the dynamic binding of the scope and the DOM .

Iii. compile and link in the directive

1.compile

Compile the operation of modifying or adding DOM nodes primarily.

/* * *     Compile function    *     * @param telem-template element    * @param tattrs-attributes of the template Element    *    /function(TElem, Tattrs)        {//  ...    };

  Let's look at a section of code that defines the compile function:

  

Use the compile function to change the original Dom (template element) before NG creates the original Dom instance and creates the scope instance.

can be applied to situations where multiple element instances need to be generated, only one template element, Ng-repeat is the best example, it is in the compile function phase to change the original DOM to generate multiple original DOM nodes, Each then generates an element instance. Because compile only runs once, you can improve performance when you need to generate multiple element instances.

2.link

Post-link

/*  * *     post-link function    *     * @param scope-scope associated with this istance    * @param ielem-instance Element    * @param iattrs-attributes of the instance element    *    /function( Scope, Ielem, iattrs) {        //  ...    };

If you only use a link function when defining the instruction, NG will treat the function as a post-link, so we'll discuss the function first.
When Ng has traversed all the DOM and run through all the compile functions, the associated Post-link function is called backwards .

The DOM now starts to reverse and executes the Post-link function, so the previous reverse call looks a bit strange, in fact it makes sense.

When running instruction Post-link that contains sub-directives, the reverse Post-link rule guarantees that the post-link of its sub-directives are already running.

That's why people think Post-link is the safest or default place to write business logic.

  But why is this element different from the compile?

Once NG invokes the compile function of the instruction, it creates an element instance object of the template element and provides it with a scope object, which may be a new instance, or it may already exist, possibly a child scope, It is also possible to have a separate scope, which depends on the scope attribute value in the directive definition object. So when linking occurs, this instance element and the scope object are already available, and are passed to the parameter list of the Post-link function as a parameter by NG.

So the element parameter object of the Post-link (pre-link) function is an element instance rather than a template element.

Pre-Link

/* * *     pre-link function    *     * @param scope-scope associated with this istance    * @param ielem-instance Element    * @param iattrs-attributes of the instance element    *    /function( Scope, Ielem, iattrs) {        //  ...    };

When you write a post-link function, you can guarantee that the Post-link function of all its child directives is executed when the Post-link function is executed.

In most cases, it can be done better, so usually we will use it to write instruction code.

However, NG provides us with an additional hook mechanism, which is the Pre-Link function, which guarantees that the Post-link function of all child instructions is executed. Run some other code.

This sentence is worth repeated deliberation, and the Pre-Link function is guaranteed to execute before the post-link of the element instance and all its child instructions are run. So it makes it quite meaningful to reverse-execute the Post-link function, which itself is the original order to execute the Pre-Link function.

This also means that the Pre-Link function runs before the Pre-Link function of all its child instructions, so the complete reason is that the Pre-Link function of an element is guaranteed to be executed before the Post-link and pre-link of all its child instructions are run. .

The difference between 4.compile and link

  

Iv. isolation scopes and data binding

1. Isolation scopes

  Typically, when we need to create reusable builds, we need directives with isolation scopes. It does not depend on the context or the scope of the parent, so it can be migrated at will without the need to consider data dependent issues.

The isolation scope is simple to implement as long as the "scope" value in the custom directive return object is written as "{}".

App.directive (' HelloWorld ',function() {  return{scope: {}, Restrict:' AE ', replace:true, Template:' <p style= ' Background-color:{{color}} ' >hello world</p> ', Link:function(Scope, Elem, attrs) {Elem.bind (' Click ',function() {elem.css (' Background-color ', ' white '); Scope. $apply (function() {Scope.color= "White";      });      }); Elem.bind (' MouseOver ',function() {elem.css (' Cursor ', ' pointer ');    }); }  };});

2. Data binding

In the case of an isolation scope, we also need to access the properties of the parent scope from within the directive in order for the code to work correctly. The good news is that angular gives you enough flexibility to selectively pass through the properties of the parent scope in a binding way.

"@" one-way text binding

In the following instruction definition, we specify that the attribute in the isolation scope color is bound to the parameter colorattr on the HTML element where the directive resides. In the HTML markup, you can see that the {{color}} expression is assigned to the COLOR-ATTR parameter. When the value of an expression changes, the color-attr parameter changes as well. The value of the color attribute in quarantine scope is also changed accordingly.

function () {  return  {    scope: {      ' @colorAttr '    }, ...    .     // The rest of the configurations   };});

The updated HTML tag code is as follows:

<body ng-controller= "Mainctrl" >  <input type= "text" ng-model= "color" placeholder= "Enter a Color"/>  

We call this way a single binding, because in this way you can only pass the string (using the expression {{}}) to the parameter. When the properties of the parent scope change, the property values in your quarantine scope model change. You can even monitor the change of the scope property within the command and trigger some tasks. However, the reverse transfer does not work. You cannot change the value of a parent scope by manipulating the isolation scope property.

Note: When isolating the scope property and the directive element parameter's name, you can set the scope binding in a much simpler way:

function () {  return  {    scope: {      ' @ '    },    ....     // The rest of the configurations   };});

The HTML code for the corresponding instruction is as follows:


= Bidirectional binding

Let's change the definition of the directive to look like this:

function () {  return  {    scope: {      ' = '    },    ....     // The rest of the configurations   };});

The corresponding HTML modifications are as follows:

<body ng-controller= "Mainctrl" >  <input type= "text" ng-model= "color" placeholder= "Enter a Color"/>  

Unlike @, this approach allows you to specify a real scope data model for a property, rather than a simple string. This allows you to pass simple strings, arrays, and even complex objects to the isolation scope. It also supports two-way binding. Whenever the parent scope property changes, the properties in the corresponding isolation scope also change, and vice versa. As before, you can also monitor the change of the scope property.

"&" executes a function in the parent scope

Sometimes it is necessary to call the functions defined in the parent scope from the isolation scope. To be able to access the functions defined in the external scope, we use &. For example, we want to invoke the SayHello () method from within the directive. The following code tells us what to do:

function () {  return  {    scope: {      ' & '    }, ...    .     // The rest of the configurations   };});

The corresponding HTML code is as follows:

<body ng-controller= "Mainctrl" >  <input type= "text" ng-model= "color" placeholder= "Enter a Color"/>  <say-hello sayhelloisolated= "SayHello ()"/></body>

Parent scope, child scope, and isolation scope differences

As a angular novice, you may be confused when choosing the right command scope. By default, the directive does not create a new scope, but instead inherits the parent scope. But in many cases, this is not what we want. If your instructions use the properties of the parent scope heavily, or even create new properties, the parent scope is contaminated. It is not a good idea to have all instructions use the same parent scope, because anyone can modify the properties in this scope. Therefore, the following principle may help you to choose the right scope for your instructions.

1. Parent scope (SCOPE:FALSE) – This is the default condition. If your instruction does not manipulate the properties of the parent Scoe, you do not need a new scope. In this case, the parent scope can be used.

2. Sub Scope (Scope:true) – This creates a new scope for the directive, and the prototype inherits from the parent scope. You should create a new scope if the properties and methods in your instruction scope are not related to other directives and to the parent scope. In this way, you also have the properties and methods defined in the parent scope.

3. Isolate scope (scope:{}) – It's like a sandbox! When you create an instruction that is self-contained and reusable, you need to use this scope. You will create many of the scope properties and methods in the instructions, which are used only within the directives and are never known by the outside world. If so, the scope of isolation is a better choice. The quarantined scope does not inherit the parent scope.

V, transclusion (embedding)

Transclusion is a way for us to include arbitrary content in our instructions. We can delay the extraction and compile the embedded content under the correct scope, eventually placing them in the location specified in the instruction template. If you set transclude:true in the instruction definition, a new embedded scope is created, and it is prototyped to inherit the child parent scope. If you want your instructions to use the isolated scope, but what it contains can be done in the parent scope, transclusion can also help.

Let's say we register a command like this:

function () {  return  {    true,    scope: {},    ' <div ng-transclude ></div> '  };});

It is used as follows:

<div output-text>  <p>hello {{name}}</p></div>

Ng-transclude indicates where the embedded content is placed. In this example, the DOM content <p>hello {{name}}</p> is extracted and placed inside the <div ng-transclude></div>. One important point to note is that the property corresponding to the expression {{name}} is defined in the parent scope, not the child scope.

Six, controller and require

If you want to allow other instructions to interact with your instructions, you need to use the controller function. For example, in some cases, you need to implement a UI component by combining two instructions. Then you can add a controller function to the instruction in the following way.

 app.directive (' outerdirective ', function    () { return   {scope: {}, Restrict:  ' AE '  function   ($scope, $compile, $http) { //< /span> $scope is the appropriate scope for the directive  this . addChild = function  (nesteddirective) { //  refers to the controller  Console.log, ' Got the message from nested direct      Ive: ' +

This code adds a controller named Outerdirective to the instruction. When another instruction wants to interact, it needs to declare its reference to your command controller instance (require). This can be done in the following ways:

function () {  return  {    scope: {},    ' AE ',    ' ^outerdirective ',     function(scope, Elem, Attrs, controllerinstance) {      //theFourth argument is the controller instance you require      scope.message = "Hi, Parent directive";      Controllerinstance.addchild (scope);};}  );

The corresponding HTML code is as follows:

<outer-directive>  <inner-directive></inner-directive></outer-directive>

Require: ' ^outerdirective ' tells angular to search for the controller in the element and its parent element. The controller instance that is found will be passed into the link function as a fourth parameter. In our example, we send the scope of the embedded instruction to the father's instruction.

ANGULARJS instruction Detailed

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.