angularJS 自定义指令 方法属性:compile、link

    自定义指令还有compile属性,这个属性是一个function, 在其中能够更改dom元素,或者进行dom元素的事件绑定等。该function中能够返还一个function,返还的这个function就是link。 自定义指令的link属性,也是一个function,一般在其中绑定dom元素的事件。javascript

示例:html

html:java

<div ng-app="myApp">
    <div ng-controller="firstController">
        <h3>一个dom上使用两个指令:custom-tags 和 custom-tags2</h3>
        <!-- step1.div先转化成dom结构
             step2.再按指令的优先级依次执行相应指令的compile方法  -->
        <ul>
            <li ng-repeat="user in users" custom-tags custom-tags2></li>
        </ul>
    </div>
</div>
js:

var i=0;
angular.module('myApp',[])

    //定义第一个指令:customTags
    .directive('customTags',function(){
        return {
            restrict:'ECAM',
            template:'<div>{{ user.name }}</div>',
            replace:true,
            //定义了compile就不需定义link,当compile返回一个方法这个方法就是link
            //tElement 正在执行该指令的当前dom元素的jquery对象
            //tAttrs   正在执行该指令的当前dom元素的属性
            compile:function(tElement,tAttrs,transclude){
                //第一个指令的编译阶段...
                console.log('customTags compile 编译阶段...');

                //若要改变dom元素,应在compile中作,此处在当前dom元素中添加一个<span>
                tElement.append(angular.element('<span> {{user.count}}</span>'));

                return {
                    //pre:编译阶段以后执行
                    pre:function preLink(scope,iElement,iAttrs,controller){
                        console.log('customTags preLink..');
                    },
                    //post:全部子元素指令的post都执行后执行,此处设置了dom元素的点击事件
                    post:function postLink(scope,iElement,iAttrs,controller){

                        iElement.on('click',function(){
                            scope.$apply(function(){
                                scope.user.name=' click after';
                                scope.user.count= ++i;
                            });
                        });
                        
                        console.log('customTags post end.');
                        console.log('');
                    }
                };

                //compile也可直接返回一个方法,这就是 postLink,也就是上面的post
                /*return function (){
                    console.log('compile return this function')
                }*/
            },
            //进行scope绑定及事件绑定
            link:function(scope,iElement,iAttrs,bookListController){
                //link不会再执行了,由于这里定义的就是postLink
            }
        }
    })

    //定义第二个指令:customTags2
    .directive('customTags2',function(){
        return {
            restrict:'ECAM',
            replace:true,
            compile:function(tElement,tAttrs,transclude){
                console.log('customTags2 compile 编译阶段...');
                return {
                    pre:function preLink(){
                        console.log('customTags2 preLink..');
                    },
                    post:function postLink(){
                        console.log('customTags2 post end.');
                    }
                };
            }
        }
    })

    .controller('firstController',['$scope',function($scope){
        $scope.users=[
            {id:10,name:'张三',count:0}
        ]
    }]);

执行结果:jquery



点击“张三”一次后:app



再点击一次:dom



改变控制器内的初始数据为:post

$scope.users=[
            {id:10,name:'张三',count:0},{id:20,name:'李四',count:0}
        ]

则执行结果为:this


点击“张三”位置一次:spa


再点击“李四”位置一次:rest


再再点击“李四”位置一次:


     

    示例中,在一个<li>上同时使用了两个angularJS自定义指令,custom-tags和custom-tags2。当一个dom上同时使用两个指令时,只能在其中一个指令中定义template,不然会出错。

   关注一下两个指令的控制台输出,表现出的两个指令内部代码的执行顺序:

customTags compile 编译阶段...
customTags2 compile 编译阶段...
customTags preLink..
customTags2 preLink..
customTags2 post end.
customTags post end.

customTags preLink..
customTags2 preLink..
customTags2 post end.
customTags post end.

   若是在customTags2后面再使用customTags3,则内部代码执行顺序:

customTags compile 编译阶段...
customTags2 compile 编译阶段...
customTags3 compile 编译阶段...
customTags preLink..
customTags2 preLink..
customTags3 preLink..
customTags3 post end.
customTags2 post end.
customTags post end.
 
customTags preLink..
customTags2 preLink..
customTags3 preLink..
customTags3 post end.
customTags2 post end.
customTags post end.

    能够看出,针对每个应用多个指令的dom,先依次执行指令的编译阶段,再依次执行指令的preLink代码,而post代码则是等待本身后面的指令的post都执行结束后再执行(多个指令的post执行有种栈的感受)。