Recherche…


Introduction

Vous en apprendrez davantage sur la fonctionnalité de directives d'AngularJS. Vous trouverez ci-dessous des informations sur les directives, ainsi que des exemples élémentaires et avancés de leur utilisation.

Paramètres

Paramètre Détails
portée Propriété pour définir le champ d'application de la directive. Il peut être défini sur false, true ou comme une portée d'isolat: {@, =, <, &}.
scope: faux La directive utilise la portée parent. Aucune portée créée pour la directive.
scope: true La directive hérite prototypiquement de la portée parent en tant que nouvelle étendue enfant. S'il existe plusieurs directives sur le même élément demandant une nouvelle étendue, elles partageront une nouvelle étendue.
portée: { @ } Liaison à sens unique d'une propriété de portée directive à une valeur d'attribut DOM. En tant que valeur d'attribut liée au parent, elle changera dans la portée de la directive.
scope: {=} Liaison d'attribut bidirectionnelle qui modifie l'attribut dans le parent si l'attribut de directive change et inversement.
scope: {<} Liaison à sens unique d'une propriété de portée directive et d'une expression d'attribut DOM. L'expression est évaluée dans le parent. Cela surveille l'identité de la valeur parente afin que les modifications apportées à une propriété d'objet dans le parent ne soient pas reflétées dans la directive. Les modifications apportées à une propriété d'objet dans une directive seront reflétées dans le parent, puisque les deux font référence au même objet
portée: { & } Permet à la directive de transmettre des données à une expression à évaluer dans le parent.
compiler: fonction Cette fonction est utilisée pour effectuer une transformation DOM sur le modèle de directive avant l'exécution de la fonction de lien. Il accepte tElement (le modèle de directive) et tAttr (liste des attributs déclarés sur la directive). Il n'a pas accès à la portée. Il peut renvoyer une fonction qui sera enregistrée en tant que post-link ou renvoyer un objet avec pre propriétés pre et post avec sera enregistré en tant que fonctions de pre-link et post-link .
lien: fonction / objet La propriété link peut être configurée en tant que fonction ou objet. Il peut recevoir les arguments suivants: scope (directive scope), iElement (élément DOM où directive est appliquée), iAttrs (collection d'attributs d'élément DOM), controller (tableau de contrôleurs requis par directive), transcludeFn. Il est principalement utilisé pour configurer les écouteurs DOM, regarder les propriétés du modèle pour les modifications et mettre à jour le DOM. Il s'exécute après le clonage du modèle. Il est configuré indépendamment s'il n'y a pas de fonction de compilation.
fonction de pré-lien Fonction de lien qui s'exécute avant toute fonction de lien enfant. Par défaut, les fonctions de lien de directive enfant s'exécutent avant les fonctions de lien de directive parent et la fonction de pré-lien permet au parent de créer le premier lien. Un cas d'utilisation est si l'enfant a besoin de données du parent.
fonction post-lien Fonction de lien que les cadres après les éléments enfants sont liés au parent. Il est couramment utilisé pour attacher des gestionnaires d'événements et accéder aux directives enfants, mais les données requises par la directive enfant ne doivent pas être définies ici car la directive enfant a déjà été liée.
restrict: string Définit comment appeler la directive depuis le DOM. Valeurs possibles (en supposant que le nom de notre directive est demoDirective ): E - Nom de l'élément ( <demo-directive></demo-directive> ), A - Attribut ( <div demo-directive></div> ), C - Classe correspondante ( <div class="demo-directive"></div> ), M - Par commentaire ( <!-- directive: demo-directive --> ). La propriété restrict peut également prendre en charge plusieurs options, par exemple - restrict: "AC" restreindra la directive à Attribute OR Class . Si elle est omise, la valeur par défaut est "EA" (élément ou attribut).
exiger: 'demoDirective' Localisez le contrôleur de demoDirective sur l'élément actuel et injectez son contrôleur comme quatrième argument de la fonction de liaison. Jeter une erreur si non trouvé.
require: '? demoDirective' Essayez de localiser le contrôleur de demoDirective ou transmettez null au lien fn si non trouvé.
exiger: '^ demoDirective' Localisez le contrôleur de demoDirective en recherchant l'élément et ses parents. Jeter une erreur si non trouvé.
require: '^^ demoDirective' Localisez le contrôleur de demoDirective en recherchant les parents de l'élément. Jeter une erreur si non trouvé.
exiger: '? ^ demoDirective' Essayez de localiser le contrôleur de demoDirective en recherchant l'élément et ses parents ou transmettez null au lien fn s'il n'est pas trouvé.
exiger: '? ^^ demoDirective' Essayez de localiser le contrôleur de demoDirective en recherchant les parents de l'élément, ou passez null au lien fn s'il n'est pas trouvé.

Création et consommation de directives personnalisées

Les directives sont l'une des fonctionnalités les plus puissantes d'angularjs. Les directives angularjs personnalisées sont utilisées pour étendre les fonctionnalités de HTML en créant de nouveaux éléments HTML ou des attributs personnalisés pour fournir certains comportements à une balise HTML.

directive.js

// Create the App module if you haven't created it yet
var demoApp= angular.module("demoApp", []);

// If you already have the app module created, comment the above line and create a reference of the app module
var demoApp = angular.module("demoApp"); 


// Create a directive using the below syntax
// Directives are used to extend the capabilities of html element 
// You can either create it as an Element/Attribute/class      
// We are creating a directive named demoDirective. Notice it is in CamelCase when we are defining the directive just like ngModel
// This directive will be activated as soon as any this element is encountered in html

demoApp.directive('demoDirective', function () {
    
  // This returns a directive definition object
  // A directive definition object is a simple JavaScript object used for configuring the directive’s behaviour,template..etc
  return {
    // restrict: 'AE', signifies that directive is Element/Attribute directive, 
    // "E" is for element, "A" is for attribute, "C" is for class, and "M" is for comment. 
    // Attributes are going to be the main ones as far as adding behaviors that get used the most.
    // If you don't specify the restrict property it will default to "A"
    restrict :'AE',  

    // The values of scope property decides how the actual scope is created and used inside a directive. These values can be either “false”, “true” or “{}”. This creates an isolate scope for the directive.
    // '@' binding is for passing strings. These strings support {{}} expressions for interpolated values.
    // '=' binding is for two-way model binding. The model in parent scope is linked to the model in the directive's isolated scope.
    // '&' binding is for passing a method into your directive's scope so that it can be called within your directive. 
    // The method is pre-bound to the directive's parent scope, and supports arguments.
    scope: { 
      name: "@",  // Always use small casing here even if it's a mix of 2-3 words
    },                  

    // template replaces the complete element with its text. 
    template: "<div>Hello {{name}}!</div>",
                
    // compile is called during application initialization. AngularJS calls it once when html page is loaded.
    compile: function(element, attributes) {
      element.css("border", "1px solid #cccccc");
                    
      // linkFunction is linked with each element with scope to get the element specific data.
      var linkFunction = function($scope, element, attributes) {
        element.html("Name: <b>"+$scope.name +"</b>");
        element.css("background-color", "#ff00ff");
      };
      return linkFunction;
    }
  };
});

Cette directive peut ensuite être utilisée dans App en tant que:

<html>
   
   <head>
      <title>Angular JS Directives</title>
   </head>
   <body>
   <script src = "//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   <script src="directive.js"></script>   
    <div ng-app = "demoApp">
       <!-- Notice we are using Spinal Casing here -->  
       <demo-directive name="World"></demo-directive>
     
      </div>
   </body>
</html>

Modèle d'objet de définition de directive

demoApp.directive('demoDirective', function () {
  var directiveDefinitionObject = {
    multiElement:  
    priority:
    terminal:
    scope: {},  
    bindToController: {},
    controller:
    controllerAs:
    require:
    restrict:
    templateNamespace:
    template:
    templateUrl:
    transclude:
    compile: 
    link: function(){}                                  
  };
  return directiveDefinitionObject;
});
  1. multiElement - défini sur true et tous les noeuds DOM entre le début et la fin du nom de la directive seront collectés et regroupés en éléments de directive
  2. priority - permet de spécifier l'ordre à appliquer aux directives lorsque plusieurs directives sont définies sur un seul élément DOM. Les directives avec des nombres plus élevés sont compilées en premier.
  3. terminal - défini sur true et la priorité actuelle sera le dernier ensemble de directives à exécuter
  4. scope - définit le champ d'application de la directive
  5. bind to controller - lie les propriétés de l'étendue directement au contrôleur de la directive
  6. controller - fonction constructeur du contrôleur
  7. require - nécessite une autre directive et injecte son contrôleur comme quatrième argument de la fonction de liaison
  8. controllerAs - référence de nom au contrôleur dans la portée de la directive pour permettre au contrôleur d'être référencé à partir du modèle de directive.
  9. restrict - restreint la directive à Element, Attribute, Class ou Comment
  10. templateNameSpace - définit le type de document utilisé par le modèle de directive: html, svg ou math. html est la valeur par défaut
  11. template - balisage HTML qui remplace par défaut le contenu de l'élément de la directive, ou encapsule le contenu de l'élément directive si transclude est true
  12. templateUrl - URL fournie de manière asynchrone pour le modèle
  13. transclude - Extrait le contenu de l'élément où la directive apparaît et le met à la disposition de la directive. Le contenu est compilé et fourni à la directive en tant que fonction de transclusion.
  14. compile - fonction pour transformer le modèle DOM
  15. link - uniquement utilisé si la propriété compile n'est pas définie. La fonction de lien est responsable de l'enregistrement des écouteurs DOM ainsi que de la mise à jour du DOM. Il est exécuté après le clonage du modèle.

Exemple de directive de base

superman-directive.js

angular.module('myApp', [])
  .directive('superman', function() {
    return {
      // restricts how the directive can be used
      restrict: 'E',
      templateUrl: 'superman-template.html',
      controller: function() {
        this.message = "I'm superman!"
      },
      controllerAs: 'supermanCtrl',
      // Executed after Angular's initialization. Use commonly 
      // for adding event handlers and DOM manipulation
      link: function(scope, element, attributes) {
        element.on('click', function() {
          alert('I am superman!')
        });
      }
    }
  });

superman-template.html

<h2>{{supermanCtrl.message}}</h2>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
  <script src="superman-directive.js"><script/>
</head>
<body>
<div ng-app="myApp">
  <superman></superman>
</div>
</body>
</html>

Vous pouvez en savoir plus sur les fonctions de restrict et de link de la directive sur la documentation officielle d'AngularJS sur les directives.

Comment créer des composants utilisables à l'aide de directives

Les directives AngularJS contrôlent le rendu du code HTML dans une application AngularJS. Ils peuvent être un élément HTML, un attribut, une classe ou un commentaire. Les directives sont utilisées pour manipuler le DOM, en attachant un nouveau comportement aux éléments HTML, à la liaison de données et à bien d’autres encore. Certains exemples de directives fournies par angulaire sont ng-model, ng-hide, ng-if.

De même, on peut créer sa propre directive personnalisée et la rendre utilisable. Pour créer une référence de directives personnalisées. Le sens derrière la création de directives réutilisables est de faire un ensemble de directives / composants écrit par vous comme angularjs nous fournit angular.js. Ces directives réutilisables peuvent s'avérer particulièrement utiles lorsque vous disposez d'une suite d'applications / d'applications nécessitant un comportement, une apparence et une convivialité cohérents. Un exemple d'un tel composant réutilisable peut être une barre d'outils simple que vous pouvez utiliser dans votre application ou dans différentes applications, mais que vous souhaitez qu'ils se comportent de la même manière.

Tout d’abord, créez un dossier nommé resutableComponents dans votre dossier d’application et créez le fichier refrableModuleApp.js

reusableModuleApp.js:

(function(){

 var reusableModuleApp = angular.module('resuableModuleApp', ['ngSanitize']);

 //Remember whatever dependencies you have in here should be injected in the app module where it is intended to be used or it's scripts should be included in your main app  
                               //We will be injecting ng-sanitize

 resubaleModuleApp.directive('toolbar', toolbar)

 toolbar.$inject=['$sce'];

 function toolbar($sce){

     return{ 
     restrict :'AE',
        //Defining below isolate scope actually provides window for the directive to take data from app that will be using this.
        scope : {
                value1: '=',
                value2: '=',
                },

         }
     template : '<ul>  <li><a ng-click="Add()" href="">{{value1}}</a></li>  <li><a ng-click="Edit()" href="#">{{value2}}</a></li> </ul> ',
         link : function(scope, element, attrs){
           
              //Handle's Add function
              scope.Add = function(){


              };

              //Handle's Edit function
              scope.Edit = function(){

              };
     }
  }

});

mainApp.js:

(function(){
   var mainApp = angular.module('mainApp', ['reusableModuleApp']); //Inject resuableModuleApp in your application where you want to use toolbar component
   
   mainApp.controller('mainAppController', function($scope){
      $scope.value1 = "Add";
      $scope.value2 = "Edit"; 
   
   });
 
 });

index.html:

 <!doctype html>
 <html ng-app="mainApp">
 <head>
  <title> Demo Making a reusable component
 <head>
  <body ng-controller="mainAppController">
   
     <!-- We are providing data to toolbar directive using mainApp'controller -->
     <toolbar value1="value1" value2="value2"></toolbar>
  
    <!-- We need to add the dependent js files on both apps here -->
     <script src="js/angular.js"></script>
     <script src="js/angular-sanitize.js"></script>
    
     <!-- your mainApp.js should be added afterwards --->
      <script src="mainApp.js"></script>

     <!-- Add your reusable component js files here -->
      <script src="resuableComponents/reusableModuleApp.js"></script>

  </body>
 </html>

Directive sont des composants réutilisables par défaut. Lorsque vous créez des directives dans un module angulaire distinct, vous pouvez l'exporter et le réutiliser dans différentes applications angulaires. De nouvelles directives peuvent simplement être ajoutées à l'intérieur de reusableModuleApp.js et reusableModuleApp peut avoir son propre contrôleur, service, objet DDO dans la directive pour définir le comportement.

Directive de base avec modèle et une portée isolée

Création d' une directive personnalisée avec une portée isolée séparera le champ d' application dans la directive du champ extérieur, afin d'éviter que notre directive de changer accidentellement les données dans le champ parent et restreindre la lecture des données privées de la portée des parents.

Pour créer une étendue isolée tout en permettant à notre directive personnalisée de communiquer avec la portée externe, nous pouvons utiliser l'option scope qui décrit comment mapper les liaisons de la portée interne de la directive avec la portée externe.

Les liaisons réelles sont réalisées avec des attributs supplémentaires attachés à la directive. Les paramètres de liaison sont définis avec l'option scope et un objet avec des paires clé-valeur:

  • Une clé qui correspond à la propriété de portée isolée de notre directive
  • Une valeur indiquant à Angular comment lier la portée interne de la directive à un attribut correspondant

Exemple simple d'une directive avec une portée isolée:

var ProgressBar = function() {
  return {
    scope: { // This is how we define an isolated scope
      current: '=', // Create a REQUIRED bidirectional binding by using the 'current' attribute
      full: '=?maxValue' // Create an OPTIONAL (Note the '?'): bidirectional binding using 'max-value' attribute to the `full` property in our directive isolated scope 
    }
    template: '<div class="progress-back">' +
              '  <div class="progress-bar"' +
              '       ng-style="{width: getProgress()}">' +
              '  </div>' + 
              '</div>',
    link: function(scope, el, attrs) {
      if (scope.full === undefined) {
        scope.full = 100;
      }
      scope.getProgress = function() {
        return (scope.current / scope.size * 100) + '%';
      }
    }
  }
}

ProgressBar.$inject = [];
angular.module('app').directive('progressBar', ProgressBar);

Exemple d'utilisation de cette directive et liaison de données depuis la portée du contrôleur vers la portée interne de la directive:

Manette:

angular.module('app').controller('myCtrl', function($scope) {
    $scope.currentProgressValue = 39;
    $scope.maxProgressBarValue = 50;
});

Vue:

<div ng-controller="myCtrl">
    <progress-bar current="currentProgressValue"></progress-bar>
    <progress-bar current="currentProgressValue" max-value="maxProgressBarValue"></progress-bar>
</div>

Construire un composant réutilisable

Les directives peuvent être utilisées pour créer des composants réutilisables. Voici un exemple de composant "utilisateur":

userBox.js

angular.module('simpleDirective', []).directive('userBox', function() {
  return {
    scope: {
        username: '=username',
        reputation: '=reputation'
    },
    templateUrl: '/path/to/app/directives/user-box.html'
  };
});

Controller.js

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

myApp.controller('Controller', function($scope) {

    $scope.user = "John Doe";
    $scope.rep = 1250;

    $scope.user2 = "Andrew";
    $scope.rep2 = 2850;

});

myPage.js

<html lang="en" ng-app="myApp">
  <head>
    <script src="/path/to/app/angular.min.js"></script>
    <script src="/path/to/app/js/controllers/Controller.js"></script>
    <script src="/path/to/app/js/directives/userBox.js"></script>
  </head>

  <body>
  
    <div ng-controller="Controller">
        <user-box username="user" reputation="rep"></user-box>
        <user-box username="user2" reputation="rep2"></user-box>
    </div>
    
  </body>
</html>

user-box.html

<div>{{username}}</div>
<div>{{reputation}} reputation</div>

Le résultat sera:

John Doe
1250 reputation
Andrew
2850 reputation

Décorateur de directive

Parfois, vous pouvez avoir besoin de fonctionnalités supplémentaires d'une directive. Au lieu de réécrire (copier) la directive, vous pouvez modifier le comportement de la directive.

Le décorateur sera exécuté pendant la phase $ inject.

Pour ce faire, fournissez un fichier .config à votre module. La directive s'appelle myDirective, vous devez donc configurer myDirectiveDirective. (ceci dans une convention angulaire [lire à propos des fournisseurs]).

Cet exemple changera le templateUrl de la directive:

angular.module('myApp').config(function($provide){
        $provide.decorator('myDirectiveDirective', function($delegate){
             var directive = $delegate[0]; // this is the actual delegated, your directive
             directive.templateUrl = 'newTemplate.html'; // you change the directive template
        return $delegate;
    })
});

Cet exemple ajoute un événement onClick à l'élément directive lorsque l'utilisateur clique dessus, cela se produit pendant la phase de compilation.

angular.module('myApp').config(function ($provide) {
        $provide.decorator('myDirectiveTwoDirective', function ($delegate) {
            var directive = $delegate[0];
            var link = directive.link; // this is directive link phase
            directive.compile = function () { // change the compile of that directive
                return function (scope, element, attrs) {
                    link.apply(this, arguments); // apply this at the link phase
                    element.on('click', function(){ // when add an onclick that log hello when the directive is clicked.
                            console.log('hello!');
                    }); 
                };
            };
            return $delegate;
        });

    });

Une approche similaire peut être utilisée pour les fournisseurs et les services.

Héritage de directive et interopérabilité

Les directives angulaires js peuvent être imbriquées ou être interopérables.

Dans cet exemple, la directive Adir expose à la directive Bdir la portée de son contrôleur $, car Bdir nécessite Adir.

angular.module('myApp',[]).directive('Adir', function () {
        return {
            restrict: 'AE',
            controller: ['$scope', function ($scope) {
                    $scope.logFn = function (val) {
                            console.log(val);
                        }
                  }]
            }
    })

Assurez-vous de définir require: '^ Adir' (regardez la documentation angulaire, certaines versions ne nécessitent pas ^ character).

.directive('Bdir', function () {
        return {
            restrict: 'AE',
            require: '^Adir', // Bdir require Adir
            link: function (scope, elem, attr, Parent) { 
            // Parent is Adir but can be an array of required directives.
                elem.on('click', function ($event) {
                    Parent.logFn("Hello!"); // will log "Hello! at parent dir scope
                    scope.$apply(); // apply to parent scope.
                });
            }
        }
    }]);

Vous pouvez imbriquer votre directive de cette manière:

<div a-dir><span b-dir></span></div>
<a-dir><b-dir></b-dir> </a-dir>

Il n'est pas obligatoire que les directives soient imbriquées dans votre code HTML.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow