Some places seem to use the controller function for directive logic and other use link. The tabs example on the angular homepage uses controller for one and link for other directive. What is the difference between two?
I'm going to expand your question a bit and also include the compile function.
compile function - use for template DOM manipulation (i.e., manipulation of tElement = template element), hence manipulations that apply to all DOM clones of the template associated with the directive. (If you also need a link function (or pre and post link functions), and you defined a compile function, the compile function must return the link function(s) because the 'link'
attribute is ignored if the 'compile'
attribute is defined.)
link function - normally use for registering DOM listeners (i.e., $watch
expressions on the scope) as well as updating the DOM (i.e., manipulation of iElement = individual instance element). It is executed after the template has been cloned -- e.g., inside an <li ng-repeat...>
, the link function is executed after the <li>
template (tElement) has been cloned (into an iElement) for that particular <li>
element. A $watch
allows a directive to be notified of scope property changes (a scope is associated with each instance), which allows the directive to render an updated instance value to the DOM.
controller function - must be used when another directive needs to interact with this directive. E.g., on the AngularJS home page, the pane directive needs to add itself to the scope maintained by the tabs directive, hence the tabs directive needs to define a controller method (think API) that the pane directive can access/call.
For a more in-depth explanation of the tabs and pane directives, and why the tabs directive creates a function on its controller using this
(rather than on $scope
), please see this vs $scope in AngularJS controllers.
In general, you can put methods, $watches
, etc. into either the directive's controller or link function. The controller will run first, which sometimes matters (see this fiddle which logs when the ctrl and link functions run with two nested directives). As Josh mentioned in a comment, you may want to put scope-manipulation functions inside a controller just for consistency with the rest of the framework.
As complement to Mark's answer, the compile function does not have access to scope, but the link function does.
I really recommend this video; Writing Directives by Misko Hevery (the father of AngularJS), where he describes differences and some techniques. (Difference between compile function and link function at 14:41 mark in the video).
Angular convention : write business logic in controller and DOM manipulation in link.
Apart from this you can call one controller function from link function of another directive.For example you have 3 custom directives
<animal>
<panther>
<leopard></leopard>
</panther>
</animal>
and you want to access animal from inside of "leopard" directive.
http://egghead.io/lessons/angularjs-directive-communication will be helpful to know about inter-directive communication
An addition about Controller:
The signature of contoller is (from the documentation) :
controller: function($scope, $element, $attrs, $transclude, otherInjectables) {
...
},
The last one is, i think, important. Since you can inject varibales like $location, $anchorScroll, etc. to the directive by using controller. As i know, they are not available with link function.