【发布时间】:2012-09-14 20:17:07
【问题描述】:
有些地方似乎将控制器功能用于指令逻辑,而其他地方则使用链接。角度主页上的选项卡示例将控制器用于一个指令,将链接用于另一个指令。两者有什么区别?
【问题讨论】:
标签: javascript angularjs web-applications javascript-framework
有些地方似乎将控制器功能用于指令逻辑,而其他地方则使用链接。角度主页上的选项卡示例将控制器用于一个指令,将链接用于另一个指令。两者有什么区别?
【问题讨论】:
标签: javascript angularjs web-applications javascript-framework
我将稍微扩展您的问题,并包括编译功能。
编译函数 - 用于 template DOM 操作(即 tElement = 模板元素的操作),因此适用于模板的所有 DOM 克隆的操作与指令相关联。 (如果您还需要链接函数(或前链接函数和后链接函数),并且定义了编译函数,编译函数必须返回链接函数,因为如果 'compile' 属性为定义。)
链接函数 - 通常用于注册侦听器回调(即,$watch 作用域上的表达式)以及更新 DOM(即,操作 iElement = 单个实例元素) .它在模板被克隆后执行。例如,在 <li ng-repeat...> 中,链接函数在 <li> 模板 (tElement) 已被克隆(到 iElement 中)用于特定的 <li> 元素之后执行。 $watch 允许指令通知范围属性更改(范围与每个实例相关联),这允许指令将更新的实例值呈现给 DOM。
控制器功能 - 当另一个指令需要与该指令交互时必须使用。例如,在 AngularJS 主页上,pane 指令需要将自身添加到 tabs 指令维护的范围内,因此 tabs 指令需要定义一个控制器方法(想想 API),pane 指令可以访问/调用。
有关选项卡和窗格指令的更深入解释,以及为什么选项卡指令使用 this(而不是 $scope)在其控制器上创建函数,请参阅 'this' vs $scope in AngularJS controllers。
通常,您可以将方法、$watches 等放入指令的控制器或链接函数中。控制器将首先运行,这有时很重要(参见fiddle,它记录了 ctrl 和 link 函数何时使用两个嵌套指令运行)。正如 Josh 在comment 中提到的那样,您可能希望将作用域操作函数放在控制器中,以便与框架的其余部分保持一致。
【讨论】:
mouseover 等事件,另一个监听属性更改的范围。大不同。
作为对 Mark 回答的补充,compile 函数无法访问范围,但 link 函数可以。
我真的推荐这个视频; Writing Directives Misko Hevery(AngularJS 之父)在其中描述了差异和一些技术。 (编译函数和链接函数的区别14:41 mark in the video)。
【讨论】:
Angular 约定:在控制器中编写业务逻辑,在链接中编写 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,但不建议这样做,因为该元素是在链接函数中提供的
pre-link 函数用于实现当 Angular js 已经编译了子元素但在任何子元素的 post 链接被调用之前运行的逻辑
发布链接
只有链接功能的指令,angular将该功能视为post链接
post 将在编译、控制器和预链接功能之后执行,这就是为什么这被认为是添加指令逻辑的最安全和默认位置
【讨论】: