3

I'm learning directives from Thinkster, when I actually load the index.html, and hover over "Say Something", in the console i get:

["howdy", "hi", "hello"]---

I'm expecting ["hello", "howdy", "hi"]--- assuming the directives get evaluated from left to right, so first hello gets pushed into $scope.words, then howdy, then hi, but that clearly is not what happens here, what does actually go on beneath the hood?

Angular Code:

(function() {
  'use strict';

angular.module('greetings', [])

.directive("welcome", function() {
  return {
    restrict: "E",
    controller: function($scope) {
      $scope.words = [];

      this.sayHello = function() {
        $scope.words.push("hello");
      };

      this.sayHowdy = function() {
        $scope.words.push("howdy");
      };

      this.sayHi = function() {
        $scope.words.push("hi");
      };
    },

    link: function(scope, element){
      element.bind("mouseenter", function() {
        console.log(scope.words);
      });
    }
  }
})

.directive("hello", function() {
  return {
    require: "welcome",
    link: function (scope, element, attrs, welcomeCtrl) {
      welcomeCtrl.sayHello();
    }
  };
})

.directive("howdy", function() {
  return {
    require: "welcome",
    link: function (scope, element, attrs, welcomeCtrl) {
      welcomeCtrl.sayHowdy();
    }
  };
})

.directive("hi", function() {
  return {
    require: "welcome",
    link: function (scope, element, attrs, welcomeCtrl) {
      welcomeCtrl.sayHi();
    }
  };
});



})();

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Egghead Directive</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body ng-app="greetings">
  <welcome hello howdy hi>Say something!</welcome>
  <!-- Javascripts -->
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
  <script src="main.js"></script>
</body>
</html>
1
  • I'm not certain, but I think directive order evaluation on the element is not well-defined. In the JS, the directives are being defined in a certain order, but the actual calls might not be. I would find the actual DOM version of the HTML <welcome> interesting, since they might be being reordered there. Commented Jan 18, 2016 at 4:05

1 Answer 1

3

Directives have a field called 'priority' which sets the compile order. The default priority is 0 and it doesn't matter in which order you put them on the element.

.directive("hi", function() {
  return {
    require: "welcome",
    priority: 1,
    link: function (scope, element, attrs, welcomeCtrl) {
      welcomeCtrl.sayHi();
    }
  };
});

The bigger the priority the earlier it will be compiled.

from https://docs.angularjs.org/api/ng/service/$compile

priority

When there are multiple directives defined on a single DOM element, sometimes it is necessary to specify the order in which the directives are applied. The priority is used to sort the directives before their compile functions get called. Priority is defined as a number. Directives with greater numerical priority are compiled first. Pre-link functions are also run in priority order, but post-link functions are run in reverse order. The order of directives with the same priority is undefined. The default priority is 0.

Update

If the priorities are equal, the directives are compiled in alphabetical order, and then the link (post-link) functions are called in reverse.

Please refer to this for details.

Sign up to request clarification or add additional context in comments.

1 Comment

if the default priority is 0, what decides that howdy is the first one that gets called?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.