AngularJSangularjs指令中之compile与link函数详解补充

普通大家在利用ng中之命令的时节,用底链接函数最多的是link属性,下面这首文章用报大家complie,pre-link,post-link的用法及区别.

angularjs里之一声令下大神奇,允许你创造充分语义化以及高度重用的零件,可以知道呢web
components的先驱者.

网上早已发出诸多介绍怎么用指令的篇章和相关书籍,相互比较的口舌,很少生介绍compile与link的别,更别说pre-link与post-link了.

大部课程只是略的游说下compile会在ng内部采用,而且建议大家才所以link属性,大部分发令的例证里还是这样的

顿时是好不幸之,因为不易的知这些函数的别会增进而对ng内部运转机理的亮,有助于你付出再好之自定义指令.

用随后我旅来拘禁下的情一步步之错过询问这些函数是呀以及它该在什么时候用到

本文假而你早就指向指令发出得的询问了,如果无底言语强烈建议你望就首文章AngularJS
developer guide section on directives

 NG中凡如何处理指令的

启分析之前,先被我们看ng中凡哪些处理指令的.

当浏览器渲染一个页面时,本质上是读html标识,然后起dom节点,当dom树创建了后广播一个风波为咱.

当你当页面中行使script标签加载ng应用程序代码时,ng监听者的dom完成事件,查找带有ng-app属性的元素.

当找到这样的因素之后,ng开始拍卖dom以这元素的起点,所以若ng-app被上加至html元素上,则ng就会见起html元素开始拍卖dom.

由这起点开始,ng开始递归查找所有子元素里面,符合应用程序里定义好的授命规则.

ng怎样处理指令其实是依赖让它们定义时之对象属性的,你可以定义一个compile或者一个link函数,或者用pre-link和post-link函数来替代link.

就此这些函数的别呢?为什么而运她?以及什么时候以其为?

拉动在这些问题随即自己同步一步来解答这些迷团吧

一律段落代码

为了解释这些函数的区分,下面我用以一个简约容易亮的例证

1.只要你有另的题目,请不要犹豫赶快在下面加上你的评价吧.

看望下面一段子html标签代码

 

复制代码代码如下:

  <level-one>
        <level-two>
            <level-three>
                Hello 
            </level-three>
        </level-two>
    </level-one>

 

下一场是一致段落js代码

 

复制代码代码如下:

var app = angular.module(‘plunker’, []);

 

    function createDirective(name){
      return function(){
        return {
          restrict: ‘E’,
          compile: function(tElem, tAttrs){
            console.log(name + ‘: compile’);
            return {
              pre: function(scope, iElem, iAttrs){
                console.log(name + ‘: pre link’);
              },
              post: function(scope, iElem, iAttrs){
                console.log(name + ‘: post link’);
              }
            }
          }
        }
      }
    }

    app.directive(‘levelOne’, createDirective(‘levelOne’));
    app.directive(‘levelTwo’, createDirective(‘levelTwo’));
    app.directive(‘levelThree’, createDirective(‘levelThree’));

 

结果非常简单:让ng来拍卖三独嵌套指令,并且每个指令都发生和好之complile,pre-link,post-link函数,每个函数都见面于控制台里打印一推行东西来标识自己.

是例子能够吃咱们简要的刺探及ng在处理指令时,内部的流水线

代码输出

脚是一个当支配高出口结果的截图

AngularJS 1

苟想协调摸索一下此例子的口舌,请点击this plnkr,然后于控制台查看结果.

剖析代码

率先独假设注意的凡这些函数的调用顺序:

复制代码代码如下:

 // COMPILE PHASE
    // levelOne:    compile function is called
    // levelTwo:    compile function is called
    // levelThree:  compile function is called

 

    // PRE-LINK PHASE
    // levelOne:    pre link function is called
    // levelTwo:    pre link function is called
    // levelThree:  pre link function is called

    // POST-LINK PHASE (Notice the reverse order)
    // levelThree:  post link function is called
    // levelTwo:    post link function is called
    // levelOne:    post link function is called

 

这事例清晰的示出了ng在link之前编译所有的下令,然后link要而分为了pre-link与post-link阶段.

专注下,compile与pre-link的执行顺序是逐一执行的,但是post-link正好相反.

为此地方都明显标识出了不同的级差,但是compile与pre-link有啊分别吗,都是相同之推行各个,为什么还要分成两单不同的函数呢?

DOM

为挖掘的又怪一点,让咱简要的改动一下方面的代码,它吧会当相继函数里打印参数列表中之element变量

 

复制代码代码如下:

var app = angular.module(‘plunker’, []);

 

    function createDirective(name){ 
      return function(){
        return {
          restrict: ‘E’,
          compile: function(tElem, tAttrs){
            console.log(name + ‘: compile => ‘ + tElem.html());
            return {
              pre: function(scope, iElem, iAttrs){
                console.log(name + ‘: pre link => ‘ +
iElem.html());
              },
              post: function(scope, iElem, iAttrs){
                console.log(name + ‘: post link => ‘ +
iElem.html());
              }
            }
          }
        }
      }
    }

    app.directive(‘levelOne’, createDirective(‘levelOne’));
    app.directive(‘levelTwo’, createDirective(‘levelTwo’));
    app.directive(‘levelThree’, createDirective(‘levelThree’));

 

专注下console.log里的输出,除了输出原始之html标记基本无别的改变.

这个应该能强化我们对这些函数上下文的理解.

重运行代码看看

输出

下是一个以决定高出口结果的截图

AngularJS 2

假使你还惦记协调运行看效果,可以点击this
plnkr,然后以控制台里翻输出结果.

观察

输出dom的结果好暴露一些妙不可言之事体:dom内容在compile与pre-link两只函数中凡免平等的

故此来了呀啊?

Compile

我们既明白当ng发现dom构建形成时即便起拍卖dom.

据此当ng在遍历dom的当儿,碰到level-one元素,从她的概念那里打听及,要履有必备之函数

因为compile函数定义在level-one指令的命令对象里,所以其见面让调用并传递一个element对象作为它们的参数

假如您细心观察,就见面相,浏览器创建是element对象时,仍然是最好老的html标记

1.以ng中,原始dom通常用来标识template
element,所以我在定义compile函数参数时即便因此到了tElem名字,这个变量指向的就是是template
element.

要运行levelone指令中的compile函数,ng就会递归深度遍历它的dom节点,然后在level-two与level-three上面还这些操作.

Post-link

深刻摸底pre-link函数之前,让我们来瞧post-link函数.

2.万一您以概念指令的时刻只使用了一个link函数,那么ng会将此函数当成post-link来拍卖,因此我们设先讨论这个函数
当ng遍历完所有的dom并运行了所有的compile函数之后,就反向调用相关联的post-link函数.

dom现在始于反向,并执行post-link函数,因此,在事先这种反向的调用看起有点意外,其实这么做是甚有含义的.

AngularJS 3

当运行包含子指令的下令post-link时,反向的post-link规则可保证其的子指令的post-link是已经运行了之.

故,当运行level-one指令的post-link函数的当儿,我们能确保level-two和level-three的post-link其实都曾运行了了.

旋即就是是为何人们还觉得post-link是无比安全或者默认的勾作业逻辑的地方.

而是怎么这边的element跟compile里的又不同啊?

假如ng调用过三令五申的compile函数,就会创一个template
element的element实例对象,并且为她提供一个scope对象,这个scope有或是新实例,也发或是一度是,可能是单子scope,也时有发生或是独的scope,这些还得拄指令定义对象里之scope属性值

故此当linking发生常,这个实例element以及scope对象就是可用之了,并且给ng作为参数传递到post-link函数的参数列表中去.

1.己个人连续以iElem名称来定义一个link函数的参数,并且它是依向element实例的

所以post-link(pre-link)函数的element参数对象是一个element实例而无是一个template
element.

故此地方例子里之出口是不同的

Pre-link

当写了一个post-link函数,你得包在实践post-link函数的早晚,它的装有子级指令的post-link函数是已经尽了之.

当大部分底情形下,它还可以举行的还好,因此便咱们且见面使用它来编排指令代码.

但,ng也咱提供了一个外加的hook机制,那即便是pre-link函数,它能确保在履行所有子指令的post-link函数之前.运行有别的代码.

当时词话是值得反复推敲的

pre-link函数能够保证在element实例上同她的所有子指令的post-link运行前执行.

因而她而的post-link函数反往实践是一对一有含义之,它和谐是本来的逐一执行pre-link函数

随即也意为着pre-link函数运行在它们所有子指令的pre-link函数之前,所以完全的理就是是:

一个元素的pre-link函数能够确保是运作于它们具备的子指令的post-link与pre-link运行前实施之.见下图:

AngularJS 4

回顾

若我们回头看看上面原始的输出,就能够明白的认出到底有了啊:

复制代码代码如下:

    // HERE THE ELEMENTS ARE STILL THE ORIGINAL TEMPLATE ELEMENTS

 

    // COMPILE PHASE
    // levelOne:    compile function is called on original DOM
    // levelTwo:    compile function is called on original DOM
    // levelThree:  compile function is called on original DOM

    // AS OF HERE, THE ELEMENTS HAVE BEEN INSTANTIATED AND
    // ARE BOUND TO A SCOPE
    // (E.G. NG-REPEAT WOULD HAVE MULTIPLE INSTANCES)

    // PRE-LINK PHASE
    // levelOne:    pre link function is called on element instance
    // levelTwo:    pre link function is called on element instance
    // levelThree:  pre link function is called on element instance

    // POST-LINK PHASE (Notice the reverse order)
    // levelThree:  post link function is called on element instance
    // levelTwo:    post link function is called on element instance
    // levelOne:    post link function is called on element instance

 

概要

回首上面的分析我们得描述一下这些函数的界别及用情况:

Compile 函数

在ng创原始dom实例以及开创scope实例之前,使用compile函数可以更改原有之dom(template
element)的产,

足采取为当需要转变多单element实例,只生一个template
element的景况
,ng-repeat就是一个绝好之例证,它便于是compile函数阶段移旧的dom生成多个原始dom节点,然后每个又生成element实例.因为compile只见面运行一次于,所以当您待扭转多独element实例的时候是足以加强性的.

template
element以及有关的习性是开吧参数传递给compile函数的,不过这时候scope是未能够就此之:

下面是函数样子:

复制代码代码如下:

/**
    * Compile function
    * 
    * @param tElem – template element
    * @param tAttrs – attributes of the template element
    */
    function(tElem, tAttrs){

 

        // …

    };

 

Pre-link 函数

运pre-link函数可以运作有业务代码在ng执行完compile函数之后,但是于她所有子指令的post-link函数将要执行之前.

scope对象及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){

 

        // …

    };

 

Post-link 函数

应用post-link函数来施行工作逻辑,在斯阶段,它曾经清楚她装有的子指令已经编译完成而且pre-link以及post-link函数已经实施完成.

顿时即是被认为是太安全以及默认的编工作逻辑代码的原因.

scope实例以及element实例做吗参数传递给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){

 

        // …

    };

 

参考于:http://www.jb51.net/article/58229.htm

相关文章