You might have noticed that in angular there are other non-html attributes
(and elements in some cases ). These are the standard directives that come bundled with Angular itself. There is a fundamental difference between how you do DOM manipulation in JQuery and how you do the same in Angular. In JQuery, you query the DOM - what does that mean? It means that once your HTML is parsed by the DOM parser, it creates a tree structure ( your DOM tree
) and the querying is actually against this tree.
When you run the query - The querying function runs through the whole DOM tree trying to find a DOM node that you want. As and when it finds them, it collects them and returns back to you this collection of nodes. Ofcourse, smart Jquery developers often times cache these nodes ( so that they dont have to do the expensive querying operation again ). Once a DOM node is found by thus querying, with jquery, we tend to manipulate this DOM node. A manipulation could be anything from append more nodes to it, adding classes , adding styles, removing the said node etc..
Angular works slightly different in this querying part. When Angular bootstraps ( on document ready ) it goes through all the DOM nodes that are within the $rootElement ( The $rootElement is the element on which you bootstrapped - either passing it manually or using ng-app ). While going through these DOM nodes it checks the name of each DOM node and all its attributes, classes etc. It matches these names with the list of names it has already collected . The list of directives it has defined and the ones you have defined. This list is actually collected during the config phase. So, each time it matches a node name etc with a directive it has registered, it compiles it. Basically it treats the said DOM as a template - and you might have heard of compiling templates in other templating systems. When you compile a template you get back a function - which is actually the linking function. When this linking function is passed data ( which is $scope ) it returns the final output HTML - which is linked to the data. A compile function always takes a template and then returns the linking function. A linking function always takes data and returns the template.
You might be wondering why then do we never return any template when we fill in the linking functions of all the custom directives we write. That function that we write there is a post-linking function hook ( or callback ) and hence we dont have to do any kind of returning in there. The same is true when you are returning something from the compile function.
You use the compile function when you want to make modifications to the template ( Hence why you use the compile function very rarely! ). You use the linking function if you want to make modifications to the DOM element once it has been hooked up with the data.
You might also want to look at this answer for further details :
https://stackoverflow.com/a/15681173/1057639