在定义一个directive时,'controller', 'link'和'compile'的区别

StackOverflow地址

http://stackoverflow.com/questions/12546945/difference-between-the-controller-link-and-compile-functions-when-definin

问题描述

一些地方在directive逻辑中使用了controller,有些则用了link。在angular主页上的tab例子中使用了controller,但是其他例子使用了link。这两者究竟有什么区别?

最佳解答

层主更全面地阐述了此问题并增加了compile功能的解释。

  • compile方法用于模板的DOM操作(例如:操作tElement = template element),之后将适用于所有关联对应directive的克隆模板的DOM操作。(如果你需要使用到link且定义了一个compile方法,此方法的返回值必须为link方法,因为如果定义了compilelink属性会被忽略)。
  • link方法一般情况下用于注册监听的回调(例如:$watch在scope中的表达式),又或者是更新DOM(例如:操作iElement = individual instance element)。它将会在模板被克隆后执行。例如:在一个<li ng-repeat...>内,针对这个特定的li元素,link方法在模板(tElement)克隆后被执行后,$watch允许一个directive得到一个scope属性变更的推送(每个scope均与对应的示例相关联),可以让directive针对DOM写入最新的值。
  • controller方法必须被用于其他directive需要与这个directive交互的情况下。例如:在angular官网上,pane directive需要将它自己添加到被tab directive维护下的scope中,此后tabs directive需要定义一个controller方法(想想API的调用方式)使pane的directive可以访问和调用。

关于更深入的关于tabs和pane的directive的解释,以及为什么tab的directive在它的controller中使用this(而不是$scope)来创建方法,请参阅‘this’ vs $scope in AngularJS controllers

总的来说,你可以在任何一个directive的controller或者link方法内使用方法,$watches,等等。controller会先执行,这有时候会很重要(可以参考这个代码片段,其中含有两个嵌套的directive,并执行其中的controller和link方法并将结果记入Log)。楼主可能需要的是将原本针对scope操作的的方法赛到某个controller内然后保证框架剩余部分的一致性。