Quantcast
Channel: Ruben Canton
Viewing all articles
Browse latest Browse all 94

Creating directives with Angular

$
0
0

One of the main points of angular consists on adding functionalities to your html elements, so that instead of setting the effects the jQuery way: selecting the element and making that happen or adding a listener, you create an “effect”, “functionality” or “behaviour” and give it a name, and then assign it to an element by just writing it on the View. No need to access the view from the controller, only to set the directive. Let’s see a quick example:

    var app = angular.module('myApp', []);
    app.directive('helloWorld', function ($compile) {
        return {
            restrict: 'AE',
            replace: 'true',
            template: "<h1>Hello World!</h1>"
        }
    });

Now just add this HTML:

<html ng-app>
<body>
<hello-world></hello-world>
</body>
</html>

That example creates a directive named “helloWorld”, and we are adding it to our view by just including a new tag with the same name as the directive. This directive just prints “Hello World!”, replacing the “hello-world” tag, but directives can do much more. For example, you can use the property “templateUrl” to get the template from somewhere else, not use any template at all, modify the scope before it’s printed to the element or the DOM after the scope it’s printed, access its generated children, create children and add them, etc.

Templates

I already show you how to use a small template using the template property, but you can also use the templateUrl property to get a template from elsewhere, as a view. Let’s see another similar example:

<html>
<body>
  <my-angular-app ng-app></my-angular-app>
  <script>
    var app = angular.module('myApp', []);
    app.directive('myAngularApp', function ($compile) {
        return {
            restrict: 'AE',
            replace: 'true',
            templateUrl: "myTemplate.html"
        }
  </script>
</body>
</html>

And that would replace the “my-angular” tag by our angular view and make it work. Note that I set ng-app on the custom tag, not on the html one, this allows us to add apps to our html code with a mere custom tag and a call to a script were the application resides (if you have many scripts, you can use RequireJS).

Calling the directive: restrict

Let’s now pay some detail to how the directive is named and called so that you can make you owns. Angular will automatically transform the camel cased name of a directive into a snake case when we call it on the HTML. So our “helloWorld” becomes “hello-world”. Angular doesn’t mind if the HTML call is upper or lower cased (it’s case insensitive) but it does if the diretive is declared starting with a capital, so you will have to set the first word in lower case.

Once we have the name, there are different ways to call the directive, not just the one I showed, let’s see them using the hello-world example:

A. <div hello-world></div>
C. <div class="hello-world"></div>
E. <hello-world></hello-world>
M. <!-- directive: hello-world -->

Yes, you can also use a comment to set a directive. I’ve given them a letter to explain how to use the property restrict as I’m here. Have a look again at how the directive is created and you will notice that there is a property called “restrict”. Such property allows to specify which ways of calling a directive are allowed, so if you set “ACEM” you allow them all, but if you set “AC” you are only allowing those two ones.

Controller

By setting the controller property you can have a mini-controller (well, if it’s mini or not will depend on what you write in there :D ) with its own scope, and injected dependencies that will be called before the model is printed into the View. Let’s see an example:

<html>
<body ng-app>

  <helloworld>{{Greeting}}</helloWorld>

  <script>
    var app = angular.module('myApp', []);
    app.directive('helloWorld', function () {
        return {
            restrict: 'E',
            controller: function($scope, $element){
                $scope.Greeting = "Hello World!";
            }
        }
  </script>
</body>
</html>

In this example I’ve created another helloWorld directive that will set a value to the scope, which is the application’s main scope injected into the directive, though in case we are in a sub-scope (like an ng-repeat) that’s what it will be injected into the directive. Once the scope has the value we need, look how the HTML is expecting such thing to be in the scope to paint it.

But we can also access the element, the DOM object, by using the injected $element. This way you have full control of it and can read its properties, check its children or anything you may need to read. Have in mind that when in the Controller the Model has not been painted into the View yet, so be careful with what you expect to read.

Finally, as it’s a effectively a controller, we can also add other dependencies to it without any problem, like the $http or $log:

    app.directive('helloWorld', function () {
        return {
            restrict: 'E',
            controller: function($scope, $element, $http, $log){
                $scope.Greeting = "Hello World!";
            }
        }

And that will work as nicely as your main controller.

Link

Following the “life-cycle” of your Angular’s application, there’s a point in which angular will paint the Model into the View, and you may want to access what’s been painted to modify it in any way. To do that we can use the property “link”, which is very similar to the controller but with no dependency injection and being executed after the View is painted:

<html>
<body ng-app>

  <helloworld></helloWorld>

  <script>
    var app = angular.module('myApp', []);
    app.directive('helloWorld', function () {
        return {
            restrict: 'E',
            link: function(scope, element, attr){
                element.html("Hello World!");
            }
        }
  </script>
</body>
</html>

Bibliography and many thanks to

ng-newsletter – Build custom directives with AngularJS
Sitepoint – A Practical Guide to AngularJS Directives.
Jason More – Difference between controller and link.


Viewing all articles
Browse latest Browse all 94

Trending Articles