AngularJs自定义指令详解(8) - priority
priority
默认值为0.
当一个元素上声明两个指令,而且它们的priority一样,谁先被调用?这个需要分情况讲。下面先给个例子:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <script src="../lib/angular-1.3.16/angular.min.js"></script> <script src=""></script> <title></title> <script language="JavaScript"> var app = angular.module("app", []); app.directive('d1',function() { return{ link: function (scope) { scope.greeting += 'World '; } }; }).directive('d2',function() { return{ link: function (scope) { scope.greeting += 'AngularJs '; } }; }); </script> </head> <body ng-app="app"> <div ng-init="greeting='Hello '" d1 d2>{{greeting}}!</div> </body> </html>
输出:
Hello AngularJs World !
可见ng-init先行一步,把greeting赋值为'Hello ',然后是指令d2的链接函数,最后是d1
试一下,修改DOM中声明的次序:
<div d2 d1 ng-init="greeting='Hello '">{{greeting}}!</div>
没用,输出不变。
再试一下,修改JavaScript中声明的次序:
app.directive('d2',function() { return{ link: function (scope) { scope.greeting += 'World '; } }; }).directive('d1',function() { return{ link: function (scope) { scope.greeting += 'AngularJs '; } }; });
这下变了!输出为:
Hello World AngularJs !
魂淡,AngularJs居然使用字母顺序来确定链接函数谁先被调用!不信?试试把d1改名为e1,输出就会变回:
Hello AngularJs World !
这时候我们不得不使用priority了!否则代码没法看了:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <script src="../lib/angular-1.3.16/angular.min.js"></script> <script src=""></script> <title></title> <script language="JavaScript"> var app = angular.module("app", []); app.directive('d1',function() { return{ link: function (scope) { scope.greeting += 'World '; } }; }); app.directive('d2',function() { return{ priority:1, link: function (scope) { scope.greeting += 'AngularJs '; } }; }); </script> </head> <body ng-app="app"> <div d1 d2 ng-init="greeting='Hello '">{{greeting}}!</div> </body> </html>
输出:
Hello World AngularJs !
奇怪的是d2的优先级更高,为什么还是先调用了d1的链接函数?
原来我们书写链接函数的方式是一个简略方式,实际上是一个postLink:
link: function postLink( ... ) { ... }
详细的写法是这样的:
link: {
pre: function preLink(scope, iElement, iAttrs, controller) { ... },
post: function postLink(scope, iElement, iAttrs, controller) { ... }
}
preLink的执行次序是由高(优先级)至低(优先级)。
postLink的执行次序是由低至高。
验证一下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <script src="../lib/angular-1.3.16/angular.min.js"></script> <script src=""></script> <title></title> <script language="JavaScript"> var app = angular.module("app", []); app.directive('d1',function() { return{ link: { pre: function (scope) { scope.greeting += 'World '; } } }; }); app.directive('d2',function() { return{ priority:1, link: { pre: function (scope) { scope.greeting += 'AngularJs '; } } }; }); </script> </head> <body ng-app="app"> <div d1 d2 ng-init="greeting='Hello '">{{greeting}}!</div> </body> </html>
输出:
Hello AngularJs World !
至于何为postLink和preLink以及它们的区别在哪,后面再说。
下面看看有模板输出的情况:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <script src="../lib/angular-1.3.16/angular.min.js"></script> <script src=""></script> <title></title> <script language="JavaScript"> var app = angular.module("app", []); app.directive('d1',function() { return{ priority:1, template:'World' }; }); app.directive('d2',function() { return{ priority:0, template:'AngularJs' }; }); </script> </head> <body ng-app="app"> <div d1 d2></div> </body> </html>
以上代码,d1、d2都有模板,而因为d1的优先级更高,所以最终显示的是World,而d2的模板被完全无视了。
可以改一下d2的优先级为2,试试输出是否改变。