Answers:
我将扩大您的问题,并包括编译功能。
编译功能 -用于模板 DOM操纵(即,tElement =模板元素的操纵),因此适用于与指令关联的模板的所有DOM克隆的操纵。(如果您还需要一个链接函数(或之前和之后的链接函数),并且定义了一个编译函数,则编译函数必须返回链接函数,因为'link'
如果'compile'
定义了该属性,则该属性将被忽略。)
链接功能 -通常用于注册侦听器回调(即,$watch
作用域上的表达式)以及更新DOM(即,对iElement =单个实例元素的操作)。克隆模板后执行。例如,在内<li ng-repeat...>
,链接功能是在<li>
已将模板(tElement)克隆(到iElement中)该特定<li>
元素之后执行的。A $watch
允许指令通知范围属性更改(范围与每个实例相关联),这允许指令将更新后的实例值呈现给DOM。
控制器功能 -当另一个指令需要与此指令进行交互时,必须使用它。例如,在AngularJS主页上,窗格指令需要将其自身添加到tabs指令所维护的范围内,因此tabs指令需要定义一个窗格指令可以访问/调用的控制器方法(think API)。
有关tabs和pane指令以及为什么tabs指令为什么使用this
(而不是on $scope
)在其控制器上创建函数的更深入的说明,请参阅AngularJS控制器中的'this'与$ scope。
通常,您可以将方法$watches
等放入指令的控制器或链接函数中。控制器将首先运行,这有时很重要(请参见该小提琴,该日志记录了ctrl和link函数使用两个嵌套指令运行的时间)。正如Josh在评论中提到的那样,您可能希望将范围操作功能放在控制器内,只是为了与框架的其余部分保持一致。
mouseover
,另一个监听属性更改的范围。很大的区别。
作为对马克回答的补充,编译功能不能访问范围,但链接功能可以。
我真的推荐这部影片;Misko Hevery(AngularJS之父)的编写指令,他在其中描述了差异和一些技巧。(视频中14:41标记处的编译功能和链接功能之间的差异)。
角度约定:在控制器中编写业务逻辑,在链接中编写DOM操作。
除此之外,您可以从另一个指令的链接函数中调用一个控制器函数,例如,您有3个自定义指令
<animal>
<panther>
<leopard></leopard>
</panther>
</animal>
并且您想从“豹”指令内部访问动物。
http://egghead.io/lessons/angularjs-directive-communication将有助于了解指令间通信
compile
将始终在之前 执行controller
。
编译功能 -
句法
function compile(tElement, tAttrs, transclude) { ... }
控制者
预先连结
链接功能负责注册DOM侦听器以及更新DOM。克隆模板后执行。这是放置大多数指令逻辑的地方。
您可以使用angular.element在控制器中更新dom,但不建议这样做,因为link函数中提供了element
预链接功能用于实现当angular js已编译子元素但在任何子元素的post链接被调用之前运行的逻辑
链接后
仅具有链接功能的指令,角度将功能视为后链接
post将在编译,控制器和预链接功能之后执行,因此这就是为什么它被认为是添加指令逻辑的最安全和默认位置的原因