No Pain AngularJS Directives

By now you’ve got your hands dirty with Angular and are starting to build some more complicated apps. You’ve read the documentation and the samples and know about these things called “directives”. But you’re afraid — afraid that they’re too complicated and difficult. 

Fear Not, My Friend

It’s true that AngularJS directives can get pretty complicated, but they can also be pretty simple. Let’s build a really simple one that you might re-use over and over: a progress spinner.

You can see all the code for this post in action over at http://angularismagic.azurewebsites.net/simple-directive/

AngularJS directives can look like a custom HTML element. Of course, the browser doesn’t know what to do with the custom elements, but Angular will convert your custom HTML element into real, useable HTML. 

But why would you want to use a custom directive for something as simple as a spinner? Couldn’t you just drop in an img tag and use a ng-show on it? Yep. You sure could. 

If you only use the spinner once, that’s a good idea. But do we ever end up doing things just once? What if you want to use that spinner again later. Okay, just put another img tag in and do the same thing. Great! Now, what if you want to make a change? Yeah….now you need to go back and change all instances of that spinner.

Convinced yet?

By converting our spinner into a directive, we can reuse the directive throughout our app and make a change to all rendered spinners just by changing the directive once.

Here’s what our directive will look like:

     

Pretty simple, eh? So how does this turn into real HTML?

    var app = angular.module('app',[]);

    app.directive('spinner', function() {
        return {
            restrict: 'E',
            replace: true,
            template: "<div><img src='spinner.gif'/></div>"
        };
    });

That’s it! Angular will see our custom HTML tag and look for a directive named the same thing. Once it does, it will do our bidding as defined inside the directive. Let’s break that definition down line by line.

First I declare a module and call it ‘app’. I stored that in a variable name app just to reuse. Next, I tell angular to attach a directive named ‘spinner’ to the app that I have setup in the line before. This function must return an object literal. This is often where the confusion starts because there are just so many options for a directive. I’ve used only three properties.

  • restrict — This is used to tell angular in what ways your directive can be used. A, E, or AE. ‘A’ means this directive can be used as an attribute on an existing element. If I were to have used this, my HTML declaration would look like this:
        <div spinner></div>
    
    ‘E’, the option I used, means that the directive can only be used as a custom HTML element. ‘AE’ means it can be used as either.
  • replace — This means that I want the HTML from the directive to replace my custom HTML tag. If I don’t want it replaced, it simply puts the contents of the directive INSIDE my custom HTML tag.
  • template — This is the HTML that I want to replace my custom tag with. There’s a way to use an external template file, but I’ll show that later. Notice in my custom HTML, I’ve got nothing dynamic — just static HTML.

When rendered, this my custom HTML is replaced with this:

    <div ng-show="showSpinner" class="ng-hide">
        <img src="spinner.gif">
    </div>

Notice that angular kept my ng-show from the original tag so that I can change the visibility using the model. It will do this for other directives as well.

So, there you go. This is probably one of the smallest, bare minimum, AngularJS directives ever. These can get so much more complicated, but the premise is the same: creating reusable HTML components.

For lots of information about creating your own custom directive, visit the AngularJS Docs on Directives.