Différence entre les fonctions «contrôleur», «lien» et «compilation» lors de la définition d'une directive

393

Certains endroits semblent utiliser la fonction de contrôleur pour la logique directive et d'autres utilisent le lien. L'exemple d'onglets de la page d'accueil angulaire utilise un contrôleur pour une et un lien pour une autre directive. Quelle est la différence entre les deux?

user1558259
la source
2
Peut-être un aperçu plus complet des fonctions de directive: directives angulaires - quand utiliser la compilation, le contrôleur, le pré-lien et le post-lien .
Izhaki

Réponses:

635

Je vais développer un peu votre question et inclure également la fonction de compilation.

  • fonction de compilation - à utiliser pour la manipulation du modèle DOM (c'est-à-dire la manipulation de l'élément tElement = template), d'où les manipulations qui s'appliquent à tous les clones DOM du modèle associé à la directive. (Si vous avez également besoin d'une fonction de lien (ou de fonctions de lien avant et après le lien) et que vous avez défini une fonction de compilation, la fonction de compilation doit renvoyer la ou les fonctions de lien car l' 'link'attribut est ignoré s'il 'compile'est défini.)

  • fonction de liaison - normalement utilisée pour enregistrer les rappels des écouteurs (c'est-à-dire les $watchexpressions sur la portée) ainsi que pour mettre à jour le DOM (c'est-à-dire, la manipulation de iElement = élément d'instance individuel). Il est exécuté après le clonage du modèle. Par exemple, à l'intérieur d'un <li ng-repeat...>, la fonction de lien est exécutée après que le <li>modèle (tElement) a été cloné (dans un iElement) pour cet <li>élément particulier . A $watchpermet à une directive d'être notifiée des changements de propriétés de portée (une portée est associée à chaque instance), ce qui permet à la directive de restituer une valeur d'instance mise à jour au DOM.

  • fonction de contrôleur - doit être utilisée lorsqu'une autre directive doit interagir avec cette directive. Par exemple, sur la page d'accueil d'AngularJS, la directive de volet doit s'ajouter à l'étendue maintenue par la directive tabs, donc la directive tabs doit définir une méthode de contrôleur (pensez API) à laquelle la directive de volet peut accéder / appeler.

    Pour une explication plus approfondie des directives tabs et pane, et pourquoi la directive tabs crée une fonction sur son contrôleur en utilisant this(plutôt que sur $scope), veuillez voir 'this' vs $ scope dans les contrôleurs AngularJS .

En général, vous pouvez placer des méthodes, $watchesetc. dans le contrôleur ou la fonction de liaison de la directive. Le contrôleur s'exécutera en premier, ce qui compte parfois (voir ce violon qui enregistre lorsque les fonctions ctrl et link s'exécutent avec deux directives imbriquées). Comme Josh l'a mentionné dans un commentaire , vous voudrez peut-être mettre des fonctions de manipulation de portée dans un contrôleur juste pour la cohérence avec le reste du framework.

Mark Rajcok
la source
131
Cette explication devrait être dans les principaux documents AngularJS ou au moins une référence à elle
Dogoku
7
C'est une réponse informative mais je pense que c'est difficile à lire. Peut-être que plus de ponctuation et des phrases plus petites peuvent aider. Dans l'ensemble, je suis reconnaissant de la réponse.
Marty Cortez
Le compilateur $ ignore l'attribut 'link' en présence d'un attribut 'compile'. Mais qu'en est-il en présence d'un attribut «contrôleur»? Le «contrôleur» fait-il que le compilateur $ ignore l'un ou les deux attributs «link» et «compile»? Est-il possible et / ou conseillé d'utiliser une «compilation» avec un «contrôleur»?
Carl G
1
@CarlG, la présence d'un attribut contrôleur n'a aucun effet sur le compilateur $ en ce qui concerne le lien et la compilation. Vous pouvez utiliser la compilation et le contrôleur.
Mark Rajcok
1
"Les écouteurs DOM" ne sont PAS "(c'est-à-dire, les expressions $ watch sur la portée)". L'un écoute le DOM pour des événements comme mouseover, l'autre la portée des modifications de propriété. Grande différence.
Dmitri Zaitsev
56

En complément de la réponse de Mark, la fonction de compilation n'a pas accès à la portée, mais la fonction de liaison le fait.

Je recommande vraiment cette vidéo; Rédaction des directives de Misko Hevery (le père d'AngularJS), où il décrit les différences et certaines techniques. (Différence entre la fonction de compilation et la fonction de liaison à 14:41 dans la vidéo ).

Pixique
la source
3
+1 pour le lien vers la vidéo. C'est très instructif.
Rob Kielty le
2
jvandemo.com/…
EMuentes
35
  1. exécution de code avant la compilation: utilisez le contrôleur
  2. exécution de code après la compilation: utilisez Link

Convention angulaire: écrire la logique métier dans le contrôleur et la manipulation DOM dans le lien.

En dehors de cela, vous pouvez appeler une fonction de contrôleur à partir de la fonction de liaison d'une autre directive.Par exemple, vous avez 3 directives personnalisées

<animal>
<panther>
<leopard></leopard>
</panther> 
</animal>

et vous souhaitez accéder aux animaux depuis l'intérieur de la directive "léopard".

http://egghead.io/lessons/angularjs-directive-communication sera utile de connaître la communication inter-directive

Rahul
la source
18
msgstr "exécuter du code avant la compilation: utiliser le contrôleur". Ceci est une erreur; compilesera toujours exécuté avant controller .
Izhaki
Vous ne seriez pas (du moins pas d'une manière simple) en mesure d'accéder aux animaux à partir de votre directive léopard. Les directives enfants peuvent accéder aux méthodes de contrôleur dans une directive parent, mais les directives frères (comme dans l'exemple ci-dessus) ne peuvent pas s'appeler les contrôleurs les uns des autres.
Benjamin White
2
Les léopards sont-ils vraiment une sorte de panthère? Aussi, sur une note secondaire ... Pouvez-vous avoir un lien - ET - un contrôleur dans une directive?
Cody
1
oui les léopards / jaguars sont des panthères. et oui, vous avez un lien et un contrôleur dans la directive.
Rahul
1
Extrait du guide du développeur Angular: "Meilleure pratique: utilisez le contrôleur lorsque vous souhaitez exposer une API à d'autres directives. Sinon, utilisez le lien."
Martin van Driel
6

fonction de compilation -

  1. est appelé avant la fonction contrôleur et liaison.
  2. Dans la fonction de compilation, vous avez le modèle d'origine DOM afin que vous puissiez apporter des modifications sur le DOM d'origine avant qu'AngularJS n'en crée une instance et avant la création d'une étendue
  3. ng-repeat est un exemple parfait - la syntaxe d'origine est l'élément de modèle, les éléments répétés en HTML sont des instances
  4. Il peut y avoir plusieurs instances d'élément et un seul élément de modèle
  5. La portée n'est pas encore disponible
  6. La fonction de compilation peut renvoyer la fonction et l'objet
  7. renvoyer une fonction (post-link) - équivaut à enregistrer la fonction de liaison via la propriété link de l'objet config lorsque la fonction de compilation est vide.
  8. renvoyer un objet avec des fonctions enregistrées via les propriétés pre et post - vous permet de contrôler quand une fonction de liaison doit être appelée pendant la phase de liaison. Voir les informations sur les fonctions de pré-liaison et de post-liaison ci-dessous.

syntaxe

function compile(tElement, tAttrs, transclude) { ... }

manette

  1. appelé après la fonction de compilation
  2. la portée est disponible ici
  3. accessible par d'autres directives (voir attribut require)

pré-lien

  1. La fonction de liaison 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. C'est là que la majeure partie de la logique directive sera mise.

  2. Vous pouvez mettre à jour le dom dans le contrôleur en utilisant angular.element mais ce n'est pas recommandé car l'élément est fourni dans la fonction de lien

  3. La fonction de pré-liaison est utilisée pour implémenter une logique qui s'exécute lorsque js angulaire a déjà compilé les éléments enfants mais avant que l'un des liens post de l'élément enfant ait été appelé

post-lien

  1. directive qui n'a qu'une fonction de lien, angular traite la fonction comme un lien de publication

  2. le post sera exécuté après la compilation, le contrôleur et la fonction de pré-lien, c'est pourquoi c'est considéré comme l'endroit le plus sûr et par défaut pour ajouter votre logique de directive

Sunil Garg
la source