Tutoriel AngularJS : Démystifier les directives personnalisées
Publié: 2022-03-11Avec la croissance rapide de JavaScript en tant que langage à pile complète, de plus en plus d'applications utilisent des frameworks qui permettent au navigateur Web de gérer une plus grande partie du traitement de l'interface utilisateur, comme la liaison de données, la gestion des vues de données, la transformation des données et de nombreux autres services. L'un des frameworks les plus performants, extensibles et populaires est AngularJS, et l'un des composants les plus utiles du framework AngularJS est ce qu'on appelle une directive . AngularJS fournit de nombreuses directives utiles et, plus important encore, il fournit un cadre riche pour créer des directives personnalisées.
Qu'est-ce qu'une directive ? Pour faire simple, les directives sont des fonctions JavaScript qui manipulent et ajoutent des comportements aux éléments HTML DOM. Les directives peuvent être très simplistes ou extrêmement compliquées. Par conséquent, il est essentiel de bien comprendre leurs nombreuses options et fonctions qui les manipulent.
Dans ce didacticiel, les quatre fonctions qui s'exécutent lorsqu'une directive est créée et appliquée au DOM seront explorées et des exemples seront fournis. Ce message suppose une certaine familiarité avec AngularJS et les directives personnalisées. Si vous débutez avec Angular, vous apprécierez peut-être un didacticiel sur la création de votre première application AngularJS.
Les quatre fonctions du cycle de vie de la directive AngularJS
De nombreuses options peuvent être configurées et la manière dont ces options sont liées les unes aux autres est importante. Chaque directive subit quelque chose de similaire à un cycle de vie lorsque AngularJS compile et lie le DOM. Le cycle de vie de la directive commence et se termine dans le processus d'amorçage AngularJS, avant que la page ne soit rendue. Dans le cycle de vie d'une directive, quatre fonctions distinctes peuvent s'exécuter si elles sont définies. Chacun permet au développeur de contrôler et de personnaliser la directive à différents stades du cycle de vie.
Les quatre fonctions sont : compile , controller , pre-link et post-Link .
La fonction de compilation permet à la directive de manipuler le DOM avant qu'il ne soit compilé et lié, lui permettant ainsi d'ajouter/supprimer/modifier des directives, ainsi que d'ajouter/supprimer/modifier d'autres éléments DOM.
La fonction contrôleur facilite la communication directive. Les directives des frères et sœurs et des enfants peuvent demander au contrôleur de leurs frères et sœurs et de leurs parents de communiquer des informations.
La fonction de pré-lien permet une manipulation privée de $scope avant le début du processus de post-lien.
La méthode post-lien est la principale méthode de travail de la directive.
Dans la directive, la manipulation DOM post-compilation a lieu, les gestionnaires d'événements sont configurés, ainsi que les montres et d'autres choses. Dans la déclaration de la directive, les quatre fonctions sont définies ainsi.
.directive("directiveName",function () { return { controller: function() { // controller code here... }, compile: { // compile code here... return { pre: function() { // pre-link code here... }, post: function() { // post-link code here... } }; } } })
Généralement, toutes les fonctions ne sont pas nécessaires. Dans la plupart des cas, les développeurs créeront simplement un contrôleur et une fonction de post-lien en suivant le modèle ci-dessous.
.directive("directiveName",function () { return { controller: function() { // controller code here... }, link: function() { // post-link code here... } } })
Dans cette configuration, link fait référence à la fonction post-link .
Que tout ou partie des fonctions soient définies, leur ordre d'exécution est important, notamment leur exécution par rapport au reste de l'application AngularJS.
Exécution de la fonction de la directive AngularJS par rapport aux autres directives
Considérez l'extrait de code HTML suivant avec les directives parentDir , childDir et grandChildDir appliquées au fragment HTML.
<div parentDir> <div childDir> <div grandChildDir> </div> </div> </div>
L'ordre d'exécution des fonctions au sein d'une directive, et par rapport aux autres directives, est le suivant :
- Phase de compilation
- Fonction de compilation : parentDir
- Fonction de compilation : childDir
- Fonction de compilation : grandChildDir
- Contrôleur et phase de pré-liaison
- Fonction contrôleur : parentDir
- Fonction de pré-lien : parentDir
- Fonction contrôleur : childDir
- Fonction de pré-lien : childDir
- Fonction contrôleur : grandChildDir
- Fonction de pré-lien : grandChildDir
- Phase post-liaison
- Fonction post-lien : grandChildDir
- Fonction post-lien : childDir
- Fonction post-lien : parentDir
Explication de la fonction de la directive AngularJS : analyse approfondie
La phase de compilation se produit en premier. Essentiellement, la phase de compilation attache des écouteurs d'événement aux éléments DOM. Par exemple, si un élément DOM particulier est lié à une propriété $scope , l'écouteur d'événement qui lui permet d'être mis à jour avec la valeur de la propriété $scope est appliqué à l'élément DOM. Le processus de compilation commence par l'élément DOM racine à partir duquel l'application AngularJS a été amorcée et parcourt les branches du DOM en utilisant une traversée en profondeur d'abord, en compilant d'abord un parent puis ses enfants jusqu'aux nœuds feuilles.
Une fois la compilation terminée, les directives ne peuvent plus être ajoutées ou supprimées du DOM (bien qu'il existe un moyen de contourner cela en utilisant directement le service de compilation. La phase suivante est l'appel des contrôleurs et des fonctions de pré-lien pour toutes les directives. Lorsque le contrôleur est appelé, le $scope est disponible et peut être utilisé. L' élément $ injecté dans le contrôleur contient le modèle compilé mais n'inclut pas le contenu enfant transclus (le contenu transclus est le contenu entre les balises HTML de début et de fin sur lequel la directive est appliqué). Par définition, les contrôleurs d'un modèle MVC transmettent simplement le modèle à la vue et définissent les fonctions de gestion des événements. Par conséquent, le contrôleur d'une directive ne doit pas modifier le DOM de la directive pour deux raisons : cela viole l'objectif de la contrôleur, et le contenu enfant transclus n'a pas été ajouté au DOM. Alors, que fait un contrôleur au-delà de la modification de $scope ? Le contrôleur permet aux directives enfant de communiquer avec wi e directives parent. La fonction contrôleur elle-même doit être considérée comme un objet contrôleur qui sera transmis à la fonction post-lien de la directive enfant si la directive enfant le demande. Par conséquent, le contrôleur est généralement utilisé pour faciliter la communication des directives en créant un objet avec des propriétés et des méthodes qui peuvent être utilisées par ses directives sœurs et enfants. La directive parent ne peut pas déterminer si une directive enfant peut nécessiter son contrôleur, il est donc préférable de limiter le code de cette méthode aux fonctions et propriétés qui peuvent être utilisées en toute sécurité par les directives enfant.
Après la fonction de contrôleur, la fonction de pré-liaison s'exécute. La fonction de pré-lien est mystérieuse pour beaucoup de gens. Si vous lisez une grande partie de la documentation sur Internet et dans les livres, les gens écrivent que cette fonction n'est utilisée que dans de rares circonstances et que les gens n'en auront presque jamais besoin. Ces mêmes explications échouent alors à donner un exemple de situation où il pourrait être utilisé.

La fonction pre-link n'est vraiment pas compliquée du tout. Tout d'abord, si vous examinez le code source d'AngularJS, vous trouverez un excellent exemple de la fonction de pré-lien : la directive ng-init l'utilise. Pourquoi? C'est simplement une excellente méthode pour exécuter du code privé impliquant le $scope ; code qui ne peut pas être appelé par les directives sibling et child. Contrairement à la fonction de contrôleur, la fonction de pré-lien n'est pas transmise aux directives. Par conséquent, il peut être utilisé pour exécuter du code qui modifie le $scope de sa directive. La directive ng-init fait exactement cela. Lorsque la fonction de pré-lien pour ng-init s'exécute, elle exécute simplement le JavaScript transmis à la directive par rapport au $scope de la directive. Le résultat de l'exécution est disponible via l'héritage prototypique de $scope aux directives enfants lors de leurs exécutions de fonctions de contrôleur, de pré-lien et de post-lien, mais sans donner accès à ces directives enfants pour ré-exécuter le code dans le pré-lien du parent. fonction de lien. De plus, la directive peut avoir besoin d'exécuter un autre code non lié à la portée $ qu'elle souhaite garder privée.
Certains développeurs AngularJS expérimentés diraient que ce code privé pourrait toujours être placé dans le contrôleur et ne pas être appelé par les directives enfants. Cet argument serait vrai si la directive n'était utilisée que par le développeur d'origine qui l'avait codée, mais si la directive devait être distribuée et réutilisée par d'autres développeurs, l'encapsulation du code privé dans la fonction de pré-lien pourrait être très bénéfique. Étant donné que les développeurs ne savent jamais comment leur directive sera réutilisée au fil du temps, la protection du code privé contre l'exécution par une directive enfant est une bonne approche de l'encapsulation du code de directive. Je considère que c'est une bonne pratique de placer le code public de communication directive dans la fonction de contrôleur et le code privé dans la fonction de pré-liaison. Comme le contrôleur, le pré-lien ne doit jamais faire de manipulation DOM ni exécuter une fonction transclude, puisque le contenu des directives enfants n'a pas encore été lié.
Pour chaque directive, sa fonction de contrôleur et de pré-lien s'exécute avant la fonction de contrôleur et de pré-lien de ses directives enfants. Une fois que la phase de contrôleur et de pré-lien pour toutes les directives est terminée, AngularJS commence la phase de liaison et exécute les fonctions de post-lien pour chaque directive. La phase de liaison s'exécute à l'opposé des flux d'exécution de compilation, de contrôleur et de pré-liaison en commençant par les nœuds DOM feuilles et en remontant jusqu'au nœud DOM racine. La traversée DOM post-lien suit un chemin principalement en profondeur. Au fur et à mesure que chaque directive enfant est liée, sa fonction post-lien est exécutée.
La fonction post-link est la fonction la plus couramment implémentée dans les directives AngularJS personnalisées. Dans cette fonction, presque tout ce qui est raisonnable peut être fait. Le DOM peut être manipulé (pour lui-même et les éléments enfants uniquement), le $scope est disponible, l'objet contrôleur pour les directives parent peut être utilisé, les fonctions transclude peuvent être exécutées, etc. Cependant, il existe quelques limitations. De nouvelles directives ne peuvent pas être ajoutées au DOM car elles ne seront pas compilées. De plus, toutes les manipulations DOM doivent être effectuées à l'aide des fonctions DOM. Le simple fait d'appeler la fonction html sur l'élément DOM et de transmettre le nouveau code HTML supprimera tous les gestionnaires d'événements ajoutés lors du processus de compilation. Par exemple, ceux-ci ne fonctionneront pas comme prévu :
element.html(element.html());
ou
element.html(element.html() + "<div>new content</div>");
Le code ne modifiera pas le code HTML, mais la réaffectation de la version de chaîne des éléments DOM supprimera tous les gestionnaires d'événements créés lors du processus de compilation. En règle générale, la fonction post-link est utilisée pour connecter les gestionnaires d'événements, $watch es et $observe s.
Une fois que toutes les fonctions post-lien sont exécutées, le $scope est appliqué à la structure DOM compilée et liée, et la page AngularJS prend vie.
Tableau des fonctions de la directive
Voici un tableau répertoriant le but de chaque fonction, ce qui est disponible lors de son exécution et les meilleures pratiques sur la façon d'utiliser chaque fonction de manière appropriée.
Exécution Commande | Directif Une fonction | DOM | Transclure | $portée | Appelable par enfant |
---|---|---|---|---|---|
1 | compiler | DOM n'a pas été compilé mais le modèle a été chargé dans la zone de contenu de l'élément DOM. Des directives peuvent être ajoutées et supprimées. DOM peut être manipulé à la fois avec les fonctions DOM et le remplacement de chaîne HTML. | La fonction Transclude est disponible mais est obsolète et ne doit pas être appelée. | Indisponible. | La fonction ne peut pas être appelée par des éléments enfants. |
2 | manette | L'élément DOM compilé est disponible mais ne doit pas être modifié. Le contenu enfant transclus n'a pas été ajouté à l'élément DOM. Aucun changement DOM ne devrait se produire car il s'agit d'un contrôleur et le contenu enfant transclus n'a pas encore été lié. | La fonction Transclude est disponible mais ne doit pas être appelée. | $scope est disponible et peut être utilisé. Les paramètres de fonction sont injectés à l'aide du service $injector . | La fonction est transmise aux fonctions de liaison de directive enfant et peut être appelée par elles. |
3 | pré-lien | L'élément DOM compilé est disponible mais ne doit pas être modifié car les éléments DOM de la directive enfant n'ont pas encore été liés. | La fonction Transclude est disponible mais ne doit pas être appelée. | $scope est disponible et peut être modifié. | La fonction n'est pas appelable par les directives enfant. Mais peut appeler les contrôleurs des directives parentes. |
4 | post-lien | L'élément DOM compilé et les éléments DOM de la directive enfant sont disponibles. DOM ne peut être modifié qu'avec des fonctions DOM (pas de remplacement HTML) et seul le contenu qui ne nécessite pas de compilation peut être ajouté. Aucun ajout/suppression de directives n'est autorisé. | La fonction Transclude est disponible et peut être appelée. | $scope est disponible et peut être utilisé. | Non appelable par les enfants de la directive mais peut appeler le contrôleur des directives parent. |
Sommaire
Dans ce didacticiel sur les directives AngularJS, nous avons découvert le but, l'ordre d'exécution et les capacités et utilisations globales de chacune des quatre fonctions de directive : compile , controller , pre-link et post-link . Parmi les quatre fonctions, le contrôleur et le post-lien sont les plus couramment utilisés, mais pour les directives plus complexes nécessitant un meilleur contrôle du DOM ou nécessitant un environnement d'exécution à portée privée, les fonctions de compilation et de pré-lien peuvent être utilisées.