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!

8 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.

Leave a Reply