Angular.js directives – Difference between controller and link

Angular directives can be a black hole of thoughts, and one of those being, “where do I put code, in ‘controller’ or ‘link’?”

The short short answer: ‘link’.

The longer short answer: Ask yourself “when do I want my code to run?”

  • Before compilation? – Controller
  • After compilation? – Link

What does this mean? While I would never condone putting DOM manipulation in an angular controller, I see it constantly, and its important to know what is actually going on and when functions are run. Example Plunkr: http://plnkr.co/edit/k5fHMU?p=preview

 But, but, but, more details please!

Ok, ok, fair enough. Couple of things to note:

  1. controller ‘$scope’ and link ‘scope’ are the same thing. The difference is paramaters sent to the controller get there through Dependency Injection (so calling it ‘$scope’ is required), where parameters sent to link are standard order based funcitons.  All of the angular examples will use ‘scope’ when in the context, but I usually call it $scope for sanity reasons: http://plnkr.co/edit/lqcoJj?p=preview
  2. the $scope/scope in this example is simply the one passed in from the parent controller.
  3. ‘link’ in directives are actually the ‘post-link’ function (see rendering pipeline below). Since pre-link is rarely used, the ‘link’ option is just a shortcut to setting up a ‘post-link’ function.

So, whats a real world example? Well, when I’m deciding, I go by this:

  • “Am I just doing template and scope things?” – goes into controller
  • “Am I adding some coolbeans jquery library?” – goes in link

 But, why!?!?!

Well, here is a great example of the angular compilation and linking pipeline: http://plnkr.co/edit/CW7cF0?p=preview

What this is telling you is that all child directives link functions get executed before the parent functions link functions. So something like the below will not work:

So why do we even have a ‘controller’ in the directive, seems dumb :-p

So we can do awesome stuff like using one directives controller in another. We simply set something we want to “this” and get it using the “require” option in the directive.

Many thanks to Josh Harris for his code reviews and awesome pipeline example above!

16 thoughts on “Angular.js directives – Difference between controller and link

  1. I’m a little confused that you initially said to generally use the linking function, but your criteria for linking over controller was basically if you were doing jquery magic.

    1. Hi David, sorry for the late reply, I was out of the country. Unfortunately since you can accomplish most of the same things in either the controller or linking function from a technical perspective, I was trying to show one of the bad things that could happen if you do DOM manipulation from the controller.

      From a practical perspective, you should always put your DOM manipulations in link, and business logic in the controller, which is more of the angular convention. Some people will put both of these exclusively in link, which is fine but somewhat violates the separation of concerns principle. Bottom line, putting DOM manipulations and business logic exclusively in link is “safer” than putting them exclusively in the controller.

  2. I would like to add some other thoughts:

    From the official Angular guide on Directives (https://docs.angularjs.org/guide/directive):
    “Best Practice: use controller when you want to expose an API to other directives. Otherwise use link.”
    See their example directly below the section “Creating Directives that Communicate”.

  3. Is there any type of naming convention when using another directive’s controller inside a child directive? I see you have “exampleDirectiveCtrl”. This could easily be named ‘ctrl’ or something else I assume. Is there a way to depend on multiple directives? If that’s possible, how would you name the functions params in the link() method? Thank you for the great post!

  4. Wow, this really helped to explain Angular directives link and controller properties. Especially the “why do we need both controllers inside a directive.”

  5. Good post!

    Just confused about:

    Before compilation? – Controller
    After compilation? – Link

    Because controller function is actually executed after compilation, but before pre-linking function.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">