The Need for Directives

Exclusive offer: get 50% off this eBook here
AngularJS Directives

AngularJS Directives — Save 50%

Learn how to craft dynamic directives to fuel your single-page web applications using AngularJS with this book and ebook

$19.99    $10.00
by Alex Vanston | August 2013 | Open Source Web Development

This article by Alex Vanston, the author of the book AngularJS Directives, could almost as easily be titled "The Need for Angular", as directives make up the heart and soul of what distinguishes Angular from other JavaScript libraries and frameworks. Certainly there are other key features, Dependency Injection being one of my favorites that makes it exemplary, however none are quite as foundational to Angular as directives.

With that in mind, let's take a look at what attributes define directives and why they're best suited for frontend development, as well as what makes them different from the JavaScript techniques and packages you've likely used earlier. Hopefully, by the end you'll understand a few of the key qualities that make directives ideal for frontend web development.

(For more resources related to this topic, see here.)

What makes a directive a directive

Angular directives have several distinguishing features, but for the sake of simplicity we'll focus on just three in this article. In contrast to most plugins or other forms of drop-in functionality, directives are declarative, data driven, and conversational.

Directives are declarative

If you've done any JavaScript development before, you've almost certainly used jQuery (or perhaps Prototype), and likely one of the thousands of plugins available for it. Perhaps you've even written your own such plugin. In either case, you probably have a decent understanding of the flow required to integrate it. They all look something like the following code:

$(document).ready(function() {
$('#myElement').myPlugin({pluginOpts});
});

In short, we're finding the DOM element matching #myElement, then applying our jQuery plugin to it. These frameworks are built from the ground up on the principle of DOM manipulation. In contrast, Angular directives are declarative, meaning we write them into the HTML elements themselves. Declarative programming means that instead of telling an object how to behave (imperative programming), we describe what an object is. So, where in jQuery we might grab an element and apply certain properties or behaviors to it, with Angular we label that element as a type of directive, and, elsewhere, maintain code that defines what properties and behaviors make up that type of object:

<html>
<body>
<div id="myElement" my-awesome-directive></div>
</body>
</html>

At a first glance, this may seem rather pedantic, merely a difference in styles, but as we begin to make our applications more complex, this approach serves to streamline many of the usual development headaches.

In a more fully developed application, our messages would likely be interactive, and in addition to growing or shrinking during the course of the user's visit, we'd want them to be able to reply to some or retweet themselves. If we were to implement this with a DOM manipulation library (such as jQuery or Prototype), that would require rebuilding the HTML with each change (assuming you want it sorted, just using .append() won't be enough), and then rebinding to each of the appropriate elements to allow the various interactions.

In contrast, if we use Angular directives, this all becomes much simpler. As before, we use the ng-repeat directive to watch our list and handle the iterated display of tweets, so any changes to our scoped array will automatically be reflected within the DOM. Additionally, we can create a simple tweet directive to handle the messaging interactions, starting with the following basic definition. Don't worry right now about the specific syntax of creating a directive; for now just take a look at the overall flow in the following code:

angular.module('myApp', [])
.directive('tweet', ['api', function (api) {
return function ($scope, $element, $attributes) {
$scope.retweet = function () {
api.retweet($scope.tweet);// Each scope inherits from it's
parent, so we still have access to the full tweet object of {
author : '…', text : '…' }
};
$scope.reply = function () {
api.replyTo($scope.tweet);
};
}
}]);

For now just know that we're getting an instance of our Twitter API connection and passing it into the directive in the variable api, then using that to handle the replies and retweets. Our HTML for each message now looks like the following code:

<p ng-repeat="tweet in tweets" tweet>
<!-- ng-click allows us to bind a click event to a function on the
$scope object -->
@{{tweet.author}}: {{tweet.text}}
<span ng-click="retweet()">RT</span> |
<span ng-click="reply()">Reply</span>
</p>

By adding the tweet attribute to the paragraph tag, we tell Angular that this element should use the tweet directive, which gives us access to the published methods, as well as anything else we later decide to attach to the $scope object.

Directives in Angular can be declared in multiple ways, including classes and comments, though attributes are the most common.

Scoping within directives is simultaneously one of the most powerful and most complicated features within Angular, but for now it's enough to know that every property and function we attach to the scope is accessible to us within the HTML declarations.

Directives are data driven

Angular directives are built from the ground up with this philosophy. The scope and attribute objects accessible to each directive form the skeleton around which the rest of a directive is built and can be monitored for changes both within the DOM as well as the rest of your JavaScript code.

What this means for developers is that we no longer have to constantly poll for changes, or ensure that every data change that might have an impact elsewhere within our application is properly broadcast. Instead, the scope object handles all data changes for us, and because directives are declarative as well, that data is already connected to the elements of the view that need to update when the data changes. There's a proposal for ECMAScript 6 to support this kind of data watching natively with Object.observe(), but until that is implemented and fully supported, Angular's scope provides the much needed intermediary.

Directives are conversational

Modular coding emphasizes the use of messages to communicate between separate building blocks within an application. You're likely familiar with DOM events, used by many plugins to broadcast internal changes (for example, save, initialized, and so on) and subscribe to external events (for example, click, focus, and so on). Angular directives have access to all those events as well (the $element variable you saw earlier is actually a jQuery wrapped DOM element), but $scope also provides an additional messaging system that functions only along the scope tree. The $emit and $broadcast methods serve to send messages up and down the scope tree respectively, and like DOM events, allow directives to subscribe to changes or events within other parts of the application, while still remaining modular and uncoupled from the specific logic used to implement those changes.

If you don't have jQuery included in your application, Angular wraps the element in jqLite, which is a lightweight wrapper that provides the same basic methods.

Additionally, when you add in the use of Angular services, directives gain an even greater vocabulary. Services, among many other things, allow you to share specific pieces of data between the different pieces of your application, such as a collection of user preferences or utility mapping item codes to their names. Between this shared data and the messaging methods, separate directives are able to communicate fully with each other without requiring a retooling of their internal architecture.

Directives are everything you've dreamed about

Ok, that might be a bit of hyperbole, but you've probably noticed by now that the benefits outlined so far here are exactly in line with the best practices. One of the most common criticisms of Angular is that it's relatively new (especially compared to frameworks such as Backbone and Ember). In contrast, however, I consider that to be one of its greatest assets. Older frameworks all defined themselves largely before there was a consensus on how frontend web applications should be developed. Angular, on the other hand, has had the advantage of being defined after many of the existing best practices had been established, and in my opinion provides the cleanest interface between an application's data and its display.

As we've seen already, directives are essentially data driven modules. They allow developers to easily create a packageable feature that declaratively attaches to an element, molds to fit the data at its disposal, and communicates with the other directives around it to ensure coordinated functionality without disruption of existing features.

Summary

In this article, we learned about what attributes define directives and why they're best suited for frontend development, as well as what makes them different from the JavaScript techniques and packages you've likely used before. I realize that's a bold statement, and likely one that you don't fully believe yet.

Resources for Article:


Further resources on this subject:


AngularJS Directives Learn how to craft dynamic directives to fuel your single-page web applications using AngularJS with this book and ebook
Published: September 2013
eBook Price: $19.99
Book Price: $32.99
See more
Select your format and quantity:

About the Author :


Alex Vanston

Alex Vanston is a self-professed geek and an outdoor junkie fused together. During high-school he began teaching himself how to code and has been obsessed with learning new languages and better ways to solve problems ever since. He has been building web sites and applications professionally for the past seven years, for clients and companies around the world. Currently he lives in Denver, CO, where he loves hiking (5 14ers down, 49 to go), playing pickup sports, and water skiing when he can. He's the lead front-end developer for ZipKick, Inc, a travel startup taking off in San Francisco, CA. You can find him online at http://www.mrvdot.com, where he blogs about web development and tech.

Books From Packt


Instant AngularJS Starter [Instant]
Instant AngularJS Starter [Instant]

Mastering Ext JS
Mastering Ext JS

Ext JS 4 First Look
Ext JS 4 First Look

Learning Ext JS 4
Learning Ext JS 4

HTML5 Game Development with ImpactJS
HTML5 Game Development with ImpactJS

Ext JS 4 Web Application Development Cookbook
Ext JS 4 Web Application Development Cookbook

Backbone.js Testing
Backbone.js Testing

Instant Dependency Management with RequireJS How-to [Instant]
Instant Dependency Management with RequireJS How-to [Instant]


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
p
N
x
h
p
H
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software