• angular学习笔记(三十)-指令(7)-compile和link(2)


    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1)

    上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序.

    看一段三个指令嵌套的代码:

    html:

    <body>
      <div ng-controller="compileCtrl">
        <level-one>
          <level-two>
            <level-three>
              hello,{{name}}
            </level-three>
          </level-two>
        </level-one>
      </div>
    </body>

    js:

    /*20.8.2 指令-compile和link*/
    var appModule = angular.module('dirAppModule',[]);

      appModule.controller('compileCtrl',function($scope){
        $scope.name="code_bunny"
      });


    appModule.directive(
    'levelOne',function(){ return { restrict:'E', compile:function(tEle,tAttrs,trans){ console.log('compile→'+'levelOne'); return { pre:function(){ console.log('pre→'+'levelOne') }, post:function(){ console.log('post→'+'levelOne') } } } } }); appModule.directive('levelTwo',function(){ return { restrict:'E', compile:function(tEle,tAttrs,trans){ console.log('compile→'+'levelTwo'); return { pre:function(){ console.log('pre→'+'levelTwo') }, post:function(){ console.log('post→'+'levelTwo') } } } } }); appModule.directive('levelThree',function(){ return { restrict:'E', compile:function(tEle,tAttrs,trans){ console.log('compile→'+'levelThree'); return { pre:function(){ console.log('pre→'+'levelThree') }, post:function(){ console.log('post→'+'levelThree') } } } } });

    得到结果:

    因此,他们的执行顺序如下:

    1.从外层到内层执行指令的compile函数

    2.compile执行完毕以后,从外层到内层执行指令的pre-link函数

    3.pre-link全部执行完以后,从内层到外层执行指令的post-link函数

    代码测试地址:http://jsfiddle.net/9hoqvtja/1/

    然后我们修改一下js代码如下:

    /*20.8.2 指令-compile和link*/
    
    appModule.directive('levelOne',function(){
        return {
            restrict:'E',
            scope:true,
            compile:function(tEle,tAttrs,trans){
                console.log('compile→'+'levelOne'+tEle.html());
                return {
                    pre:function(scope,iEle,iAttrs){
                        console.log('pre→'+'levelOne'+iEle.html())
                    },
                    post:function(scope,iEle,iAttrs){
                        console.log('post→'+'levelOne'+iEle.html())
                    }
                }
            }
        }
    });
    appModule.directive('levelTwo',function(){
        return {
            restrict:'E',
            scope:true,
            compile:function(tEle,tAttrs,trans){
                console.log('compile→'+'levelTwo'+tEle.html());
                return {
                    pre:function(scope,iEle,iAttrs){
                        console.log('pre→'+'levelTwo'+iEle.html())
                    },
                    post:function(scope,iEle,iAttrs){
                        console.log('post→'+'levelTwo'+iEle.html())
                    }
                }
            }
        }
    });
    appModule.directive('levelThree',function(){
        return {
            restrict:'E',
            scope:true,
            compile:function(tEle,tAttrs,trans){
                console.log('compile→'+'levelThree'+tEle.html());
                return {
                    pre:function(scope,iEle,iAttrs){
                        console.log('pre→'+'levelThree'+iEle.html())
                    },
                    post:function(scope,iEle,iAttrs){
                        console.log('post→'+'levelThree'+iEle.html())
                    }
                }
            }
        }
    });

    我们给指令添加scope属性,在打印的过程中加入打印tEle和iEle的内容,结果如下:

    可以看到,才compile阶段打印出的元素,是没有class属性的,但是在pre-link和post-link阶段打印出的元素,class属性为ng-scope ng-binding.

    原因是:

    compile阶段得到的元素是tElement,也就是templateElement,是原始的元素.

    link阶段(无论是pre-link还是post-link),得到的是元素是iElement,也就是instanceElement,是经过compile编译后的元素的实例.

    那么原始的元素和元素的实例有什么区别呢? 我的理解(不一定对)是:tElement就是最原始的元素,也就会说,页面里写的html是啥,它就是啥.而iElement就经过了angular的编译处理了.他具体处理了一些什么事情,我现在不知道,但是就这个例子,可以看到,它至少处理了'给元素绑定scope作用域','对元素里的数据与模型进行双向绑定',当然他一定还处理了很多其他的事情...这就是为什么compile是没有scope参数的,因为它还没有编译嘛~ 

    代码测试地址:http://jsfiddle.net/0kgn110u/1/

    总结一下刚才讲的所有知识:

    1.compile函数的执行顺序是从父元素向子元素执行.当某个指令的compile被执行时,它的父元素的compile都已经被执行了.它的tEle参数和tAttrs参数,指的的原始的元素和原始元素的属性,原始元素没有经过angular编译.

    2.pre-link函数的执行顺序是从父元素向子元素执行.当某个指令的pre-link被执行时,它的父元素和它自己的compile函数,以及它的父元素的pre-link函数都已经被执行了.它的iEle参数和iAttrs参数,指的是经过ng编译的元素.

    3.post-link函数的执行顺序是从子元素向父元素执行.当某个指令的post-link被执行时,它的父元素和它自己的compile函数,以及它的子元素的post-link函数都已经被执行了.它的iEle函数和iAttrs参数,指的是,经过ng编译的元素.

    参考文献:[译]ng指令中的compile与link函数解析

    但是上面说的这一切,当指令中有template(templateUrl)的时候,它compile和link的执行顺序就不是这样的了.下一篇继续讲解这种情况.

  • 相关阅读:
    如何查看IIS的80端口被占用? 拂晓风起
    配置VSS2005(在局域网内搭建服务器) 拂晓风起
    Log4Net ,.net和SQL Server的完美结合 拂晓风起
    SQL Server简单使用配置 拂晓风起
    ztree图标不显示
    oracle添加同义词
    Struts2作用域和标签库(转)
    java实现链表(转)
    unexpected end of subtree(hql拼写有误,仔细查看hql语句,以及参数值的导入)
    http://www.mianwww.com/html/2012/10/17027.html面试题(经典)
  • 原文地址:https://www.cnblogs.com/liulangmao/p/3980256.html
Copyright © 2020-2023  润新知