Page 108 - AngularJS权威教程
P. 108
88 第 10 章 指令详解
以ng-repeat为例,它会遍历指定的数组或对象,在数据绑定之前构建出对应的DOM结构。
如果我们用ng-repeat来创建无序列表,其中的每一个<li>都会被ng-click指令所修饰,这
个过程会使得性能比手动创建列表要快得多,尤其是列表中含有上百个元素时。
与克隆<li>元素,再将其与数据进行链接,然后对每个元素都循环进行此操作的过程不同,
我们仅需要先将无需列表构造出来,然后将新的DOM(编译后的DOM)传递给指令生命周期中
的下一个阶段,即链接阶段。
一个指令的表现一旦编译完成,马上就可以通过编译函数对其进行访问,编译函数的签名包
含有访问指令声明所在的元素(tElemente)及该元素其他属性(tAttrs)的方法。这个编译函
数返回前面提到的模板函数,其中含有完整的解析树。
这里的重点是,由于每个指令都可以有自己的模板和编译函数,每个模板返回的也都是自己
的模板函数。链条顶部的指令会将内部子指令的模板合并在一起成为一个模板函数并返回,但在
树的内部,只能通过模板函数访问其所处的分支。
最后,模板函数被传递给编译后的DOM树中每个指令定义规则中指定的链接函数,
10.4.2 compile(对象或函数)
compile选项可以返回一个对象或函数。
理解compile和link选项是AngularJS中需要深入讨论的高级话题之一,对于了解AngularJS
究竟是如何工作的至关重要。
compile选项本身并不会被频繁使用,但是link函数则会被经常使用。本质上,当我们设置
了link选项,实际上是创建了一个postLink()链接函数,以便compile()函数可以定义链接函数。
通常情况下,如果设置了compile函数,说明我们希望在指令和实时数据被放到DOM中之前
进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。
compile和link选项是互斥的。如果同时设置了这两个选项,那么会把compile
所返回的函数当作链接函数,而link选项本身则会被忽略。
// ...
compile: function(tEle, tAttrs, transcludeFn) {
var tplEl = angular.element('<div>' +
'<h2></h2>' +
'</div>');
var h2 = tplEl.find('h2');
h2.attr('type', tAttrs.type);
h2.attr('ng-model', tAttrs.ngModel);
h2.val("hello");
tEle.replaceWith(tplEl);
return function(scope, ele, attrs) {
// 连接函数
};
}
//...
如果模板被克隆过,那么模板实例和链接实例可能是不同的对象。因此在编译函数内部,我