In the last two tutorial blogs, AngularJS Custom Directive and AngulaJS Isolate Scope, we have learnt about creating our own custom directives and isolate their scopes from their parent scopes.

In this tutorial, we are going to dive deep into the custom directive and will learn some of the important concepts and tricks of the AngularJS custom directive.

link function

link function is basically used to manipulate the DOM( Document Object Model ) element using custom directive.  link option in custom directive registers DOM listener and also update the DOM.


Watch the live demo or download code from the link given below.


link function is used as an option in the custom directive as given below.

angular.module("myApp", [])
 // Registering custom directive
.directive('myProduct', function(){
return{
...
...

link: function(scope, element, attrs, controller, transcludeFn){
// Write your code here...
}

...
...

};
});

link function accepts some arguments. Let’s have a look at each of them.

  • scope: – It is an Angular scope object.
  • element: –  It is the jqLite-wrapped element that is matched by this custom directive.
  • attrs: –  It is a hash object having key-value pairs of normalized attribute names with their corresponding attribute values.
  • controller: – This is the directive’s required controller instance(s). If the directive has its own controller, then the controller’s name can be used as an argument.
  • transcludeFn: – It is a transclude linking function pre-bound to the correct transclusion scope.

Note:- You can change the name of each argument according to you like, change scope to s or element to elem. But, the order of each argrument should be same as mentioned in the code.

Let’s understand the use of link function through an example.

Note: – In this example, we are going to use and modify the same code of custom directive that we create in the last blog of custom directive, i.e AngularJS Isolate Scope.

To read and download the earlier code, click here…

Hope you have downloaded the code from the above-mentioned link. So, let’s move ahead and modify the products by adding some behaviour to each product.

In this example, we are going to add a behaviour that when the user will put the mouse cursor over any of the product, the size of product will get zoom.

myController.js

// Application Module
angular.module("myApp", [])
// Single controller for all product
.controller("productController", ['$scope', function($scope) {
$scope.prod_alert = false;
// Adding inkthemes as a property to scope
$scope.products = [{
"product_name": 'InkThemes',
"product_img_link": 'inkthemes',
"product_link": 'https://www.inkthemes.com/market/'
}, {
"product_name": 'Aorank',
"product_img_link": 'aorank',
"product_link": 'https://www.formget.com/product/seo-php-script/'
}, {
"product_name": 'MailGet',
"product_img_link": 'mailget',
"product_link": 'https://www.formget.com/mailget/'
}, {
"product_name": 'Formget',
"product_img_link": 'formget',
"product_link": 'https://www.formget.com/'
}];
}])
// Registering custom directive
.directive('myProduct', function() {
return {
templateUrl: 'templates/product_page.html',
// Isolated scope for this directive
scope: {
productInfo: "=showProduct"
},
// Using link function add behaviour to each products
link: function(scope, element, attrs){
// Adding zooming property to each product on mouseenter
element.on('mouseenter', function(event){
angular.element(element[0].children[0]).css({'background':'#DEDDDD', "transform" : 'scale(1.2)',"margin-bottom" : "50px","margin-top" : "50px"});
});
// Resizing the product to its original size on mouseleave
element.on('mouseleave', function(event){
angular.element(element[0].children[0]).css({'background':'#F1F1F1', "transform" : 'scale(1)', "margin-bottom" : "0","margin-top" : "30px"});
});
}
};
});

Have a look at the link function code, i.e

// Using link function add behaviour to each products
link: function(scope, element, attrs){
// Adding zooming property to each product on mouseenter
element.on('mouseenter', function(event){
angular.element(element[0].children[0]).css({'background':'#DEDDDD', "transform" : 'scale(1.2)',"margin-bottom" : "50px","margin-top" : "50px"});
});
// Resizing the product to its original size on mouseleave
element.on('mouseleave', function(event){
angular.element(element[0].children[0]).css({'background':'#F1F1F1', "transform" : 'scale(1)', "margin-bottom" : "0","margin-top" : "30px"});
});
}

In this function, we are triggering an event when the user will enter the mouse over the product. It will applying some CSS to the outer div of the product, i.e element[0].children[0]. to zoom its size.

Similarly, when the use will remove the mouse cursor from the product, another event will trigger and it will resize the product to its original size.

Tips:- To inspect or find the position of any element, such as div, p, id or class, use console.log(element) inside link function and see the output in your browser’s console.

Similar things you can do for scope and attrs argument to see what object or data it actully contain.

index.html

It is the main view file of the application and display all the products.

<html ng-app="myApp">
<head>
<title>Angular Link Function</title>
<!-- Latest Bootstrap compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Include Application's CSS file -->
<link rel="stylesheet" href="css/style.css">
<!-- Include AngularJS library -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<!-- Include Application's JS file -->
<script src="js/myController.js"></script>
</head>
<body>
<div class="container main" ng-controller="productController">
<div class="row">
<h1 class="text-center">Angular Link Function Demo</h1>
<div class="col-xs-8 col-xs-offset-2 col-md-3 col-md-offset-0" ng-repeat="p in products">
<!-- Used custom directive as an element to show products -->
<my-product show-product="p"></my-product>
</div>
</div>
</div>
</body>
</html>

product_page.html

This template is used by the custom directive to show different products in the application’s view.

<!-- Template containing layout of each product -->
<div class='product-wrapper'>
<h3 class='text-center'><a href='{{productInfo.product_link}}'>{{productInfo.product_name}}</a></h3>
<div class='product'>
<img ng-src='img/{{productInfo.product_img_link}}.png' alt='{{productInfo.product_name}}'/>
<div class='clearfix'></div>
<div class='button text-center'>
<a href='{{productInfo.product_link}}' class='btn btn-danger'>Visit Site</a>
</div>
</div>
</div>

style.css

It contains all the CSS code used in the application.

@import url(http://fonts.googleapis.com/css?family=Raleway);
body{
min-height: 960px;
}
.main{
margin-top: 15px;
}
h1{
font-family:raleway;
margin-bottom: 20px;
}
h3 a{
color:#545151;
font-family:raleway;
}
.product-wrapper{
border:2px solid #E2E2E2;
padding: 0 10px 10px 10px;
background: #F1F1F1;
margin-top: 30px;
border-radius: 5px;
min-width: 200px;
font-family:raleway;
}
.product-wrapper img{
width: 98%;
border:1px solid #DEDEDE;
margin-bottom: 10px;
}

Conclusion:

Hope you got the concept of link function in AgularJS Custom Directive. Use it in your application and provide us your feedback from the commenting space given below. Keep in touch with us for more intersting code and tricks 🙂