$compile

Is the service responsible for compiling the view and linking it to the appropriate scope.

What is a "View"?

A view is HTML, plain and simple. A view is a DOM element and it's children. Views will contain markup and directives in that markup.

What Views are "Compiled"?

All views are compiled by Angular. This is done by code that lives in the $compile service area of Angular.

How does view compilation work?

View compilation in Angular is some of the most ingenious functional programming I've seen in JavaScript. It works (very, very roughly) like this:

  1. Step into a DOM node.
  2. Loop through registered directives to see if this node contains any.
  3. For each directive found:
    1. Determine if the current scope is to be used, or if a child or isolated scope needs to be created.
    2. Create a function that, when called, will execute the directive's linking function against the appropriate scope from step 3.1.
    3. Append that function to a list of functions to be executed later.
  4. Does the current DOM node have children?
    1. YES: Step into each one and go to step 1 above.
    2. NO: That's the end of this branch.
  5. Return a function that will execute all functions created in Step 3.2. This is your compiled view. Binding a View to a Scope This is done when the compiled view is called and a scope is passed to it.

When does this occur?

When you angular app is initially bootstrapped. During the processing of some directives, such as ng-repeat, it will be called on a subsection of your views.

When ng-view is updated after a routing event it's called on the incoming view. When ng-include changes, it's called on the incoming view.

When should I use $compile?

Truthfully? Almost never. It's going to be pretty rare that you should have to compile some HTML and process it as a view. Generally, you can just use directives that already exist to do whatever it is you think you need to do with $compile. But I suppose there are some edge cases where you may want to use it. Such as creating a completely custom repeater or something like that.

If you do find yourself needing to use compile. It should almost always be in a directive. Think about it: $compile is creating a function to wire up directives to a scope... in essence setting up all interactions between your app and the DOM. When you see "DOM", it's a directive. Directives are where we should be manipulating the DOM and nowhere else.