Você está na página 1de 2

AngularJs:

--------------------

How do angular directives work in a nutshell:

We begin with a template (as a string or loaded to a string)

var templateString = '<div my-directive>{{5 + 10}}</div>';

Now, this templateString is wrapped as an angular element


var el = angular.element(templateString);

With el, now we compile it with $compile to get back the link function.
var l = $compile(el)

Here is what happens,

$compile walks through the whole template and collects all the directives that it recognizes.

All the directives that are discovered are compiled recursively and their link functions are collected.
Then, all the link functions are wrapped in a new link function and returned as l.

Finally, we provide scope to this l (link) function which further executes the wrapped link functions with this scope and their corresponding elements.
l(scope)

This adds the template as a new node to the DOM and invokes controller which adds its watches to the scope which is shared with the template in DOM.

Comparing compile vs link vs controller :

Every directive is compiled only once and link function is retained for re-use. Therefore, if there's something applicable to all instances of a directive should be performed inside
directive's compile function.

Now, after compilation we have link function which is executed while attaching the template to the DOM. So, therefore we perform everything that is specific to every instance of the
directive. For eg: attaching events, mutating the template based on scope, etc.

Finally, the controller is meant to be available to be live and reactive while the directive works on the DOM (after getting attached). Therefore:
(1) After setting up the view[V] (i.e. template) with link. $scope is our [M] and $controller is our [C] in M V C
(2) Take advantage the 2-way binding with $scope by setting up watches.
(3) $scope watches are expected to be added in the controller since this is what is watching the template during run-time.
(4) Finally, controller is also used to be able to communicate among related directives. (Like myTabs example in https://docs.angularjs.org/guide/directive)
(5) It's true that we could've done all this in the link function as well but its about separation of concerns.

Therefore, finally we have the following which fits all the pieces perfectly :

The controller function/object represents an abstraction model-view-controller (MVC). While there is nothing new to write about MVC, it is still the most significant advanatage of angular:
split the concerns into smaller pieces. And that's it, nothing more, so if you need to react on Model changes coming from View the Controller is the right person to do that job.
The story about link function is different, it is coming from different perspective then MVC. And is really essential, once we want to cross the boundaries of
a controller/model/view (template).
Let' start with the parameters which are passed into the link function:
function link(scope, element, attrs) {

scope is an Angular scope object.


element is the jqLite-wrapped element that this directive matches.
attrs is an object with the normalized attribute names and their corresponding values.
To put the link into the context, we should mention that all directives are going through this initialization process steps: Compile, Link. An Extract from Brad Green and Shyam Seshadri
book Angular JS:
Compile phase (a sister of link, let's mention it here to get a clear picture):
In this phase, Angular walks the DOM to identify all the registered directives in the template. For each directive, it then transforms the DOM based on the directives rules (template,
replace, transclude, and so on), and calls the compile function if it exists. The result is a compiled template function,
Link phase:
To make the view dynamic, Angular then runs a link function for each directive. The link functions typically creates listeners on the DOM or the model. These listeners keep the view and
the model in sync at all times.
A nice example how to use the link could be found here: Creating Custom Directives. See the example: Creating a Directive that Manipulates the DOM, which inserts a "date-time"
into page, refreshed every second.
Just a very short snippet from that rich source above, showing the real manipulation with DOM. There is hooked function to $timeout service, and also it is cleared in its destructor call to
avoid memory leaks
.directive('myCurrentTime', function($timeout, dateFilter) {
function link(scope, element, attrs) {
...
// the not MVC job must be done
function updateTime() {
element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
}
function scheduleUpdate() {
// save the timeoutId for canceling
timeoutId = $timeout(function() {
updateTime(); // update DOM
scheduleUpdate(); // schedule the next update
}, 1000);
}
element.on('$destroy', function() {
$timeout.cancel(timeoutId);
});

Você também pode gostar