Directive link function’s usage in Angular.js

 We already know that Angular.js has a directive controller with scope then what is the need of the directive link function in Angular.js. Both controller and link functions have access to scope. The directive links don't have Angular features like two way binding but we can use angular’s API with it. First thing first, let’s see how directive’s in general work. Let’s start with the template.

var templateString = '
{{5 + 10}}
';
The string is now wrapped as an angular element.
var el = angular.element(templateString);
We now compile el with $compile.
var l = $compile(el)
$compile goes through the template and collects all directives it recognizes. These directives are compiled recursively and their link functions are collected. These link functions are then wrapped in a new link function and returned as l. Now we give scope functions to this l function, again it executes the wrapped link functions with this scope and its related elements.
l(scope)
Finally the template is added as a new node to DOM and invokes the controller , the controller adds watches to scope to share it with the template in DOM. Let’s see a real time example. Our example consists of electronics equipment sales with buy buttons as links. When we click on the item it will be replaced with a demo message. Simple DOM manipulation.
.directive('itemWidget', [function() {
    return{
        ...
        link : function(scope, element, attrs){
             
                //Add event listener for 'click' event
            element.on('click', function(event) {
                        //Update DOM.                       
                    element.html('Thanks for buying this item.');
                    element.css({
                        color: 'green'
                    });
              });
        }
    }
}]);
For this example we have included DOM manipulation logic in our link function. When you click an item we apply CSS on that item and replace it with a dummy message.


<html>

    <head>  

        <title>Directive Demo</title>  

        <link rel="stylesheet" href="<a class="vglnk" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="nofollow"><span>https</span><span>://</span><span>maxcdn</span><span>.</span><span>bootstrapcdn</span><span>.</span><span>com</span><span>/</span><span>bootstrap</span><span>/</span><span>3</span><span>.</span><span>3</span><span>.</span><span>5</span><span>/</span><span>css</span><span>/</span><span>bootstrap</span><span>.</span><span>min</span><span>.</span><span>css</span></a>" rel="stylesheet"/>

    </head>

    <body class="jumbotron container" ng-app="myApp">

        <div ng-controller="AppController as ctrl">

            <h3>List of Sale Items.</h3>

            <div ng-repeat="bla in ctrl.items">

                <item-widget item="bla" promo="Christmas-Sale" on-select="ctrl.onItemSelect(selectedItem)"></item-widget>

            </div>

        </div>

       

        <script src="<a class="vglnk" href="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js" rel="nofollow"><span>https</span><span>://</span><span>ajax</span><span>.</span><span>googleapis</span><span>.</span><span>com</span><span>/</span><span>ajax</span><span>/</span><span>libs</span><span>/</span><span>angularjs</span><span>/</span><span>1</span><span>.</span><span>4</span><span>.</span><span>4</span><span>/</span><span>angular</span><span>.</span><span>js</span></a>">

        </script>  

        <script>

            angular.module('myApp', [])

            .controller('AppController', [function() {

                var self = this;

                self.items = [

                            {name: 'Computer', price: 500, condition:'New',brand : 'Lenovo', published:'01/11/2015'},

                            {name: 'Phone', price: 200, condition:'New',brand : 'Samsung', published:'02/11/2015'},

                            {name: 'Printer', price: 300, condition:'New',brand : 'Brother', published:'06/11/2015'},

                            {name: 'Dishwasher', price: 250, condition:'Second-Hand',brand : 'WhirlPool', published:'01/12/2015'},

                            ];

                self.onItemSelect = function(name) {

                    console.log('Congrats. You have just bought a', name);

                };                          

            }])

            .directive('itemWidget', [function() {

                return{

                    restrict: 'E',

                    scope: {

                        item: '=',

                        promo: '@',

                        pickMe : '&onSelect'

                    },

                    templateUrl: 'saleItem3.html',

                    link : function(scope, element, attrs){

                            //Add event listener for 'click' event

                        element.on('click', function(event) {

                         

                                element.html('Thanks for buying this item.');

                                element.css({

                                    color: 'green'

                                });

                          });

                    }

                }

            }]);

        </script>

    </body>

</html>


Template partial is:


<div class="panel panel-default">

    <div class="panel-heading">

        Published at:<span ng-bind="item.published | date"></span> &nbsp;Promotion: {{promo}}<button class="pull-right" ng-click="pickMe({selectedItem:item.name})">Buy me</button>

    </div>

    <div class="panel-body">

            Name:<span ng-bind="item.name"></span>

            Condition:<span ng-bind="item.condition"></span>

            Price:<span ng-bind="item.price | currency"></span>

            Brand:<span ng-bind="item.brand"></span>

    </div>

</div>