搜索

首页  >  问答  >  正文

angular.js - angular指令的compile的参数(tElement,tAttrs)和link中的参数(scope,iElement,iAttrs)究竟有什么区别?

RT:
自己编写angular指令:

        compile:function(tElement,tAttrs,linker){

            return function(scope,iEle,iAttrs,ctrl,linker){

            }
        }

compile函数有三个参数(tElement,tAttrs,linker),
link函数有五个参数(scope,iElement,iAttrs,ctrl,linker)
其中的tElement和iElement,tAttrs和iAttrs在什么情况下会不一样?
经过很多种尝试,指令嵌套指令,都没有发现他们有区别,但是看书上说是会不一样的,请问在什么场景下会不一样,有没有栗子?

--------------------------分割线--------------------------------------
看完这篇文章,文章中的levelOne嵌套levelTwo嵌套levelThree,compile和link的执行顺序应该是:
compile-levelOne,compile-levelTwo,compile-levelThree,即先把compile全部执行完,然后再执行link函数.
但是我自己写的这两个指令,它的执行顺序却不是这样的,它是先执行了外层的compile,外层的link,然后再执行内层的compile,内层的link...
希望能得到大师指点,谢谢~~~

  <script type="text/ng-template" id="text.html">
    <p>
      <h3 ng-transclude></h3>
    </p>
  </script>
    <p cb-repeat="thing in things">
      <my-widget name="code_bunny"><span>{{thing}}</span></my-widget>
    </p>
appModule.directive('cbRepeat',function(){
    return {
        restrict:'EAC',
        transclude:'element',
        compile:function(tEle,tAttrs,trans){
            console.log('compile-cbRepeat');
            return function(scope,iEle,iAttrs,ctrl,linker){
                console.log('post-cbRepeat');
                //scope.$new()创建一个作用域的子作用域
                //console.log(scope.$new().$parent==scope);
                var myLoop = iAttrs.cbRepeat,
                    match = myLoop.match(/\s*(.+)\s+in\s+(.*)\s*/),
                    indexString = match[1],
                    collectionString = match[2],
                    parentEle = iEle.parent(),
                    elements = [];
                scope.$watchCollection(collectionString,function(collection){
                    if(elements.length>0){
                        for(var i= 0;i<elements.length;i++){
                            elements[i].el.remove();
                            elements[i].scope.$destroy();
                        }
                        elements = [];
                    }
                    for(var i=0;i<scope[collectionString].length;i++){
                        var newScope = scope.$new();
                        newScope[indexString] = scope[collectionString][i];
                        linker(newScope,function(clone){
                            parentEle.append(clone);
                            var element = {};
                            element.el = clone;
                            element.scope = newScope;
                            element.scope.$on('$destroy',function(){
                                console.log('被移除')
                            });
                            elements.push(element);
                        })
                    }

                })
            }
        }
    }
});
appModule.directive('myWidget',function(){
    return {
        restrict:'E',
        templateUrl:'text.html',
        replace:true,
        transclude:true,
        scope:true,
        compile:function(tEle,tAttrs,trans){
            console.log('compile-myWidget'+tEle.html());
            return function(scope,iEle,iAttrs){
                console.log('post-myWidget'+iEle.html())
            }
        }        
    }
});

最后打印出来的顺序是这样的:

它是先执行了外层cbRepeat的compile,然后执行了cbRepeat的link,然后再是内层myWidget的compile,myWidget的link...
晕了~~~ 跪求解答~~~ 谢谢~~~

阿神阿神2776 天前604

全部回复(2)我来回复

  • PHPz

    PHPz2017-05-15 16:52:00

    关于指令中的compile与link函数的区别建议看这篇文章的介绍
    http://www.ifeenan.com/angularjs/2014-09-04-[%E8%AF%91]NG%E6%8C%87%E4%BB%A4%E4%B8%AD%E7%9A%84compile%E4%B8%8Elink%E5%87%BD%E6%95%B0%E8%A7%A3%E6%9E%90/

    回复
    0
  • 習慣沉默

    習慣沉默2017-05-15 16:52:00

    我看了那篇文章,也看了你的答案,我觉得是理解上的差异造成的,原文中,是说先按嵌套顺序执行 levelOne - levelThree的compile ,再按嵌套顺序执行 levelOne - levelThree的pre-link。但楼主你的例子中并没有link属性,也没有pre-link,也没有post-link,只是简单的compile。所以输出你图示的那个结果。你可以仔细看一下那篇文章中的代码和你的代码之间的不同。

    回复
    0
  • 取消回复