Mastering

angularjs-logo

Directives


By @PascalPrecht

#HannoverJS 28th Mar '13

Hi!

This is me
(@PascalPrecht)

me

My neighbor.
He likes coding.
But he can't.

neoskop-logo

heartworking heart
neoskop-logo

<3

me

And I like that!

WTF directives ?

Directives are a way to teach HTML new tricks!

Example:

Drag the heart!


// The code you actually use
<h2>Drag the heart!</h2>
<div draggable></div>

Directive code

app.directive('draggable', function($document) {
    var startX=0, startY=0, x = 0, y = 0;
    return function(scope, element, attr) {
      element.css({
       position: 'relative',
       cursor: 'pointer'
      });
      element.bind('mousedown', function(event) {
        startX = event.screenX - x;
        startY = event.screenY - y;
        $document.bind('mousemove', mousemove);
        $document.bind('mouseup', mouseup);
      });

      function mousemove(event) {
        y = event.screenY - startY;
        x = event.screenX - startX;
        element.css({
          top: y + 'px',
          left:  x + 'px'
        });
      }

      function mouseup() {
        $document.unbind('mousemove', mousemove);
        $document.unbind('mouseup', mouseup);
      }
    }
  });

Cool, what else?

Re-usable components



Angular is what?! Awesome.


<tabs>
  <tab title="Tab 1">
    Angular is what?! 
  </tab>
  <tab title="Tab 2">
    Awesome.
  </tab>
</tabs>

Not cool enough?


Okay. One more try.

This is a Zippy.

Click around and have some fun with it...



Zippy's content


<zippy title="Click to toggle">
  Zippy's content
</zippy>

And this...

ZippyCeption!!!!!!

Yeap. You can do that.



<zippy title="Let's kick some asses!">
  <zippy title="WTF...?!">
    <zippy title="Nesting?">
       .... and so on
    </zippy>
  </zippy>
</zippy>

Yeap.

Angular is the only framework that can do that!

Think of angular as a better browser rather then a framework.

- Miško Hevery


True that is!

Let's dive in!

Angular comes with a lot of built-in directives


To see a list of built-in directives click the link below, check out the 'directive' section on the left and try out the examples.




⊂(◉‿◉)つ
awesomeness

So how does this work?

Behind the scenes

Manual and compiling and linking



window.onload = function() {
  var $rootElement = angular.element(window.document);
  var modules = [
    'ng',
    'myApp',
    function($provide) {
      $provide.value('$rootElement', $rootElement)
    }
  ];
  var $injector = angular.injector(modules);
  var $compile = $injector.get('$compile');
  var compositeLinkFn = $compile($rootElement);

  var $rootScope = $injector.get('$rootScope');
  compositeLinkFn($rootScope);

  $rootScope.$apply();
}
            

Building your own directives

(short version)

Definition:


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

app.directive('directiveName', function factory(injectables) {

  return function linkFn(scope, iElement, iAttrs) {
    // Logic which has access to instance element,
    // scope and instance attributes
  };

});

Example:

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

app.directive('alertFoo', function () {
  return function (scope, element, attrs) {
    element.bind('hover', function () {
      alert('foo');
    });
  );
});

Usage:

<ANY foo></ANY>

Result:

<ANY foo class="foo"></ANY>

Working sample? Click here!

Directive Definition Object

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

app.directive('foo', function () {
  return {
    priority: 0,
    template: '<div></div>',
    templateUrl: 'template.html',
    replace: false,
    transclude: false,
    restrict: 'A',
    scope: false,
    compile: function compile(tElement, tAttrs, transclude) {
      return {
        pre: function (scope, iElement, iAttrs, controller) {}
        post: function (scope, iElement, iAttrs, controller) {}
      }
    },
    link: function postLink(scope, iElement, iAttrs) {}
  };
});

Let's take deeper look

Directive Restriction

In Angular you can ...


  • ...define directives as attribute

  • ...define directives as class

  • ...define directives as element

  • ...define directives as comment



⊂(◉‿◉)つ
awesomeness

Priorizing Directives

Things to notice:



  • Directives are linked in a Depth-First, Bottom-Up approach


  • ng-controller has it's own link timing. Controllers are linked top-down


  • You can change your directives link timing behavior with priorities



⊂(◉‿◉)つ
awesomeness

Directive Scope

A directives scope can...





...and there's more

⊂(◉‿◉)つ
awesomeness

Things to notice:



  • If more than one directive requests a new scope, only one new scope is created


  • Isolated scope doesn't prototypically inherit


  • You can define your directives interface through attributes (@, =, &)

Transclusion

Zippy uses transclusion



Zippy's content


<zippy title="Click to toggle">
  Zippy's content
</zippy>


⊂(◉‿◉)つ
Dig it

Things to notice:



  • A transcluded scope is a sibling of an isolated scope


  • A transcluded scope prototypically inherits from parent scope


Wanna get started?



For real examples take a look at:




neoskop-logo

is hiring!