Angular JS: What is the need of the directive’s link function when we already had directive’s controller with scope?

后端 未结 3 712
天涯浪人
天涯浪人 2020-11-28 17:13

I need to perform some operations on scope and the template. It seems that I can do that in either the link function or the controller function (si

3条回答
  •  余生分开走
    2020-11-28 17:41

    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 directive’s 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);
     });
    
     ...
    

提交回复
热议问题