AngularJS Directives - The Reminder You Need To Bookmark

AngularJS Directives - The Reminder You Need To Bookmark


Feb 23 2016, 21:20 in Web Development

Angular.js is probably the most known Javascript Framework, at close range with React.js

A few months ago I started to learn about Angular, and I've made a brand new website from scratch, at my job. So we can say I turbo-learned this framework. I am now proud to say that I master Angular pretty well.

One thing I've been using a lot are directives, and these are very particular because they offer a lot of amazing features. I'm basically building my project structures around directives as they offer this nice and proper way to break down your app into re-usable modules.

But there are some particular options and settings that are complicated to assimilate and to remember.

Now, I won't cover everything about directives and the topics I'll mention (this is not the purpose of this article), but you need to have a basic understanding of Angular and Directives to be confortable with my below explanations.

The purpose of this article is to be a big snippet / reminder where you'll be able to quickly remember some important things, like what's the difference between "=" and "@" in a directive's scope.

Speaking of which, let's jump into the subject:

Scope

(function() {
    'use strict';
    angular
        .module('myApp')
        .directive('myDirective', myDirective);

    function myDirective() {
        var directive = {
            templateUrl: 'layout.html',
            controller: 'DemoController',
            controllerAs: 'demo',
            bindToController: true,
            scope: {
                someText: '@' // Text binding / one-way binding
                someObject: '=' // Model binding / two-way binding
                someMethod: '&' // Method binding
            }
        };

        return directive;

    }
})();

There are three different options and you should very easily understand their meaning with the comment I've put right next to the symbols

You can use @ if you simply need to pass a string or a whatever information you want to pass. Like a token, an ID, a slug, a username, whatever.
But what you need to know is that, if you update this data in the directive's controller, for example, well it won't update at the source. That the one-way binding.

The = symbol is probably the one you'll use the most. Let's say I have a blog article with a some comments at the bottom. I can display the article datas, and then loop through all comments and display them. Well in this case I could use a directive and passe the whole comment's object to it. Like this :

    <div ng-repeat="comment in post.comments" comment="comment"></div>

Finally & will simply allow you to pass a method to your directive, so you'll be able to call this method inside your directive controller. This can be very helpful in order to avoid the ugly $broadcast event..

Note that you will need to set bindToController to true if you want to be able to access the datas inside a controller..

Restrictions

I never quite used this option, as if you stick with a clean and proper code, you shouldn't have any issue. But sometimes, it can be very useful.

The purpose of the Restrict option allows you to specify how the directive has to be called in your html. AngularJS provides four of them, each symbolized by a capital letter.

Let's review some code:

(function() {
    'use strict';
    angular
        .module('myApp')
        .directive('myDirective', myDirective);

    function myDirective() {
        var directive = {
            // Choose one of these
            restrict: 'A', // <div my-directive></div>
            restrict: 'E', // <my-directive></my-directive>
            restrict: 'C', // <div class="my-directive"></div>
            restrict: 'M', // <!-- directive: my-directive -->

            // Multiple options is possible
            restrict: 'AECM',

            controller: 'DemoController',
            controllerAs: 'demo',
        };

        return directive;

    }
})();

As you can see there are four different restrictions, A for attribute, E for element (basically html tag), C for class and M for comment. You will have to include your directive by the way you specified by this option, otherwise it won't work at all.

Compile vs Link

That is a very tricky one.

The best way to remember it is : compile is stronger than link because you can do more.

With the link method, you will be able to execute some code when the directive is loaded, and send data to the controller, or manipulate the DOM in several ways.

With the compile method, you can do all that, but even more : tell angular that your transcluded content is linked to a controller ! This allows you to put content with some methods into your directive HTML tag (like ng-repeat), grab it and inject it into the directive template. That's what ng-repeat is exactly doing.

I'm not going to explain ng-transclude in detail, as the official documentation is well done.

Compile method is executed in three calls : the compile phase, the pre-link phase and the post-link phase:

(function() {
    'use strict';
    angular
        .module('myApp')
        .directive('myDirective', ['$compile', myDirective]);

    function myDirective($compile) {
        var directive = {
            compile: function(element, attributes, linker) {
                console.log('First Step');
                return {
                    pre: function($scope, $element, $attr, $controller){
                        console.log('Second');
                    },
                    post: function($scope, $element, $attr, $controller){
                        console.log('Third');
                        $compile($element)($scope); // Exemple of actual compilation
                    },
                }
            }

            controller: 'DemoController',
            controllerAs: 'demo',
        };

        return directive;

    }
})();

If you want manipulate the generated DOM in your directive, you have to put your code into the post method, for example.

There's an awesome article here that will provide the full explanation of these particular methods. As said in the beginning, this is not the purpose of my article :)

Hopefully you'll get all the good reminders from this post and if you are developing an angular app, and thinking "damn, what was the symbol I need again?" well you can come here and find it in a super easy way !

Happy JS,

Clément


Share:
Like:

Disable AdBlock on this domain and offer me a cup of coffee :)