9.22.2015

3 Ways to Master AngularJS Directives

For AngularJs, the most powerful component continues to be directives. Let’s understand what directives mean here. It is nothing but an extended version of the HTML attributes with the prefix ng added to it. With the ng-app, you can initialize the AngularJS application. Similarly, using the ng-init directive you can initialize the application data. In this article, we will talk mostly about the custom directives, and how you can master these directives thus making your AngularJS based application worthy for users. Remember, your aim is to offer a good application that can empower the users.

Simple Directives

If you want to create a widget that would arrange the different profile details that you are planning to display on your application, then you should ideally use simple directives. It offers a creative view of the elements.

Here is an example of a widget created to view the book details on an e-commerce application

angular.module('masteringAngularJsDirectives', [])
.directive('book', function() {
 return {
 restrict: 'E',
 scope: {
 data: '='
 },
 templateUrl: 'templates/book-widget.html'
 }
})

With this, you have created a directive first, which has been named book for this example. This directive returns an object. Restrict will define the directive type- attribute, class, element or comment. Scope gives you an idea of the directive’s scope. With templateURL, you can view content for render specific content. This will remove the complications associated with HTML

Isolated Scope

When you talk of directives, you will see an underlying scope alongside each directive. Data binding is an important element of directive declaration. For this example, we will consider implementing the basket portion of the e-commerce application.

Here’s how you can declare the directive in your application

app.directive("item", function() {
 return {
 restrict: 'E',
 link: function(scope, element, attrs) {
 scope.name = attrs.name;
 },
 template: '<div><strong>Name:</strong> {{name}} <strong>Select Amount:</strong> <select name="count" ng-model="count"><option value="1">1</option><option value="2">2</option></select> <strong>Selected Amount:</strong> {{count}}</div>'
 }
})

Let’s say you want to display three items using HTML, here’s how you would do that

<item name="Item-1"></item>
<item name="Item-2"></item>
<item name="Item-3"></item>

The basic issue here is that when you wish to update a particular item, all the items in the amounts section get updated. The reason being there is a two way data binding being done here, and the scope is not isolated here. Here’s how you can isolate the scope

 

app.directive("item", function() {
 return {
 restrict: 'E',
 scope: {},
 link: function(scope, element, attrs) {
 scope.name = attrs.name;
 },
 template: '<div><strong>Name:</strong> {{name}} <strong>Select Amount:</strong> <select name="count" ng-model="count"><option value="1">1</option><option value="2">2</option></select> <strong>Selected Amount:</strong> {{count}}</div>'
 }
})

Directive Inheritance

What if you have a feature that will be used by several directives? You just need to introduce it to a parent directive, and allow it to be used by all the child directives. Let’s say you want to initiate a mouse click event for a book directive, and it is going to be used by another directive as well. Here’s how you can get it done

app.directive('mouseClicked', function() {
 return {
 restrict: 'E',
 scope: {},
 controller: "MouseClickedCtrl as mouseClicked"
 }
})

This is your parent directive which will eventually be used by the child directives too. You will need to define a controller directive too

app.controller('MouseClickedCtrl', function($element) {
 var mouseClicked = this;
 mouseClicked.bookType = null;
 mouseClicked.setBookType = function(type) {
 mouseClicked.bookType = type
 };
 
 $element.bind("click", function() {
 alert("Typeof book: " + mouseClicked.bookType + " sent for statistical analysis!");
 })
})

Set the controller instance for the variable booktype while using child directives.

app.directive('ebook', function() {
 return {
 require: "mouseClicked",
 link: function(scope, element, attrs, mouseClickedCtrl) {
 mouseClickedCtrl.setBookType("EBOOK");
 }
 }
})
.directive('magazine', function() {
 return {
 require: "mouseClicked",
 link: function(scope, element, attrs, mouseClickedCtrl) {
 mouseClickedCtrl.setBookType("MAGAZINE");
 }
 }
})

A require keyword is generally used by the child directive

<a><mouse-clicked ebook>Game of thrones (click me)</mouse-clicked></a><br/>
<a><mouse-clicked magazine>PC World (click me)</mouse-clicked></a>

You need to understand the child directives are assets of the parent directive, and will act on their command.

When you have gained expertise on managing the AngularJS directives, then you can manage the pages of the application in a more determined manner, without working too much on the code. The user experience will be enhanced with the use of directives, and the debugging would be less complicated.

Semaphore Software offers expertise in AngularJS application development. Get in touch with us via info@silvertouch.com, to discuss your requirements further.

1 comment: