Que se passe-t-il d'autre entre ces appels de fonction ?
Les différentes fonctions directives sont exécutées à l'intérieur de deux autres fonctions angulaires appelées $compile
(lorsque la directive compile
est exécuté) et une fonction interne appelée nodeLinkFn
(lorsque la directive controller
, preLink
y postLink
sont exécutées). Plusieurs choses se produisent au sein de la fonction angulaire avant et après l'appel des fonctions directives. L'élément le plus remarquable est sans doute la récursivité de l'enfant. L'illustration simplifiée suivante montre les étapes clés des phases de compilation et de liaison :
Pour illustrer ces étapes, utilisons le code HTML suivant :
<div ng-repeat="i in [0,1,2]">
<my-element>
<div>Inner content</div>
</my-element>
</div>
Avec la directive suivante :
myApp.directive( 'myElement', function() {
return {
restrict: 'EA',
transclude: true,
template: '<div>{{label}}<div ng-transclude></div></div>'
}
});
Compiler
En compile
L'API se présente comme suit :
compile: function compile( tElement, tAttributes ) { ... }
Les paramètres sont souvent précédés du préfixe t
pour indiquer que les éléments et attributs fournis sont ceux du modèle source, plutôt que ceux de l'instance.
Avant l'appel à compile
le contenu transclu (le cas échéant) est supprimé et le modèle est appliqué au balisage. Ainsi, l'élément fourni au modèle compile
se présentera comme suit :
<my-element>
<div>
"{{label}}"
<div ng-transclude></div>
</div>
</my-element>
Remarquez que le contenu transclu n'est pas réinséré à ce stade.
Après l'appel à la fonction .compile
Angular parcourra tous les éléments enfants, y compris ceux qui viennent d'être introduits par la directive (les éléments du modèle, par exemple).
Création d'une instance
Dans notre cas, trois instances du modèle source ci-dessus seront créées (par ng-repeat
). Ainsi, la séquence suivante sera exécutée trois fois, une fois par instance.
Contrôleur
En controller
L'API implique :
controller: function( $scope, $element, $attrs, $transclude ) { ... }
En entrant dans la phase de liaison, la fonction de liaison est renvoyée par l'intermédiaire de $compile
est désormais doté d'un champ d'application.
Tout d'abord, la fonction de lien crée un champ d'application enfant ( scope: true
) ou une portée isolée ( scope: {...}
) si elle est demandée.
Le contrôleur est alors exécuté, avec la portée de l'élément d'instance.
Pré-lien
En pre-link
L'API se présente comme suit :
function preLink( scope, element, attributes, controller ) { ... }
Il ne se passe pratiquement rien entre l'appel à la directive .controller
et le .preLink
fonction. Angular fournit tout de même des recommandations quant à l'utilisation de chacune d'entre elles.
Suite à la .preLink
la fonction de lien parcourt chaque élément enfant - en appelant la fonction de lien correcte et en lui attachant la portée actuelle (qui sert de portée parentale pour les éléments enfants).
Post-lien
En post-link
est similaire à celle de l'API pre-link
fonction :
function postLink( scope, element, attributes, controller ) { ... }
Il convient peut-être de noter qu'une fois que la directive .postLink
est appelée, le processus de liaison de tous ses éléments enfants est terminé, y compris tous les éléments .postLink
fonctions.
Cela signifie qu'au moment où .postLink
est appelé, les enfants sont "vivants" et prêts. Cela comprend :
- liaison de données
- transclusion appliquée
- champ d'application ci-joint
À ce stade, le modèle se présente donc comme suit :
<my-element>
<div class="ng-binding">
"{{label}}"
<div ng-transclude>
<div class="ng-scope">Inner content</div>
</div>
</div>
</my-element>