Maison > Article > interface Web > Explication détaillée des fonctions de compilation et de liaison dans les instructions angulairejs_AngularJS
Habituellement, lorsque les gens utilisent des instructions en ng, la fonction de lien la plus couramment utilisée est l'attribut de lien. L'article suivant vous expliquera l'utilisation et les différences de complie, pré-lien et post-lien.
Les directives d'angularjs sont très magiques, vous permettant de créer des composants très sémantiques et hautement réutilisables. Il peut être compris comme le pionnier des composants Web.
Il existe de nombreux articles et livres connexes sur la façon d'utiliser les instructions sur Internet. Par rapport aux autres, il existe peu d'introductions à la différence entre compiler et créer un lien, sans parler du pré-lien et du post-lien.
La plupart des tutoriels disent simplement que compile sera utilisé en interne dans ng, et il est recommandé d'utiliser uniquement l'attribut link. C'est le cas dans la plupart des exemples d'instructions
.C'est très regrettable, car comprendre correctement la différence entre ces fonctions améliorera votre compréhension du mécanisme de fonctionnement interne de ng et vous aidera à développer de meilleures instructions personnalisées.
Alors suivez-moi et lisez le contenu suivant étape par étape pour comprendre quelles sont ces fonctions et quand elles doivent être utilisées
Cet article suppose que vous avez déjà une certaine compréhension des directives. Sinon, il est fortement recommandé de lire cet articleSection du guide du développeur AngularJS sur les directives
Comment traiter les instructions en NG
Avant de commencer l'analyse, examinons d'abord comment les instructions sont traitées en ng.
Lorsque le navigateur affiche une page, il lit essentiellement la balise HTML, puis crée le nœud dom et nous diffuse un événement après la création de l'arborescence dom
.Lorsque vous utilisez la balise script pour charger le code de l'application ng dans la page, ng écoute l'événement d'achèvement dom ci-dessus et recherche les éléments avec l'attribut ng-app.
Lorsqu'un tel élément est trouvé, ng commence à traiter dom à partir du point de départ de cet élément, donc si ng-app est ajouté à l'élément html, ng commencera à traiter dom à partir de l'élément html.
À partir de ce point de départ, ng commence à rechercher récursivement tous les sous-éléments conformes aux règles d'instruction définies dans l'application
.La façon dont ng gère les instructions dépend en fait des attributs de l'objet lorsqu'il est défini. Vous pouvez définir une fonction de compilation ou de lien, ou utiliser des fonctions de pré-lien et de post-lien au lieu de lien.
Alors, quelle est la différence entre ces fonctions ? Pourquoi devriez-vous l'utiliser ?
Avec ces questions, suivez-moi pas à pas pour répondre à ces mystères
Un morceau de code
Pour expliquer la différence entre ces fonctions, je vais utiliser un exemple simple et facile à comprendre ci-dessous
1. Si vous avez des questions, n'hésitez pas à ajouter vos commentaires ci-dessous
Regardez le code de balise html suivant
fonction createDirective(nom){
fonction de retour(){
revenir {
restreindre : 'E',
compiler : function(tElem, tAttrs){
console.log(nom ': compile');
revenir {
pré : fonction (portée, iElem, iAttrs) {
console.log(nom ': pré-lien');
},
post : fonction (portée, iElem, iAttrs) {
console.log(nom ': lien de publication');
>
>
>
>
>
>
app.directive('levelOne', createDirective('levelOne'));
app.directive('levelTwo', createDirective('levelTwo'));
app.directive('levelThree', createDirective('levelThree'));
结果非常简单 :让ng来处理三个嵌套指令,并且每个指令都有自己的complile,pre-link,post-link函数,每个函数都会在控制台里打印一行东西来标识自己.
这个例子能够让我们简单的了解到ng在处理指令时,内部的流程
代码输出
下面是一个在控制台输出结果的截图
如果想自己试一下这个例子的话,请点击ce plnkr,然后在控制台查看结果.
分析代码
第一个要注意的是这些函数的调用顺序 :
// PHASE PRÉ-LIEN
// levelOne : la fonction de pré-lien est appelée
// levelTwo : la fonction de pré-lien est appelée
// levelThree : la fonction de pré-lien est appelée
// PHASE POST-LINK (Notez l'ordre inverse)
// levelThree : la fonction de lien de publication est appelée
// levelTwo : la fonction de lien de publication est appelée
// levelOne : la fonction de lien de publication est appelée
这个例子清晰的显示出了ng在link之前编译所有的指令,然后link要又分为了pre-link与post-link阶段.
注意下,compile与pre-link的执行顺序是依次执行的,但是post-link正好相反.
Il s'agit d'un pré-lien compilé, d'un pré-lien,为什么还要分成两个不同的函数呢 ?
DOM
为了挖的更深一点,让我们简单的修改一下上面的代码,它也会在各个函数里打印参数列表中的élément变量
function createDirective(nom){
fonction de retour(){
revenir {
restreindre : 'E',
compiler : function(tElem, tAttrs){
console.log(name ': compile => ' tElem.html());
revenir {
pré : fonction (portée, iElem, iAttrs) {
console.log(name ': pre link => ' iElem.html());
},
post : fonction (portée, iElem, iAttrs) {
console.log(name ': post link => ' iElem.html());
>
>
>
>
>
>
app.directive('levelOne', createDirective('levelOne'));
app.directive('levelTwo', createDirective('levelTwo'));
app.directive('levelThree', createDirective('levelThree'));
Faites attention à la sortie dans console.log. Hormis la sortie du balisage HTML d'origine, il n'y a fondamentalement aucun autre changement.
Cela devrait approfondir notre compréhension du contexte de ces fonctions.
Exécutez à nouveau le code et voyez
Sortie
Ce qui suit est une capture d'écran de la sortie de la console
Si vous souhaitez toujours l'exécuter vous-même pour voir l'effet, vous pouvez cliquer sur ce plnkr, puis afficher les résultats de sortie dans la console
.Observer
Le résultat de la sortie de dom peut révéler des choses intéressantes : le contenu de dom est différent dans les fonctions de compilation et de pré-lien
Alors que s'est-il passé ?
Compiler
Nous savons déjà que ng commence à traiter le dom lorsqu'il constate que la construction du dom est terminée.
Ainsi, lorsque ng traverse le dom, il rencontre l'élément de niveau un et apprend de sa définition qu'il doit exécuter certaines fonctions nécessaires
Parce que la fonction de compilation est définie dans l'objet commande de la directive de niveau un, elle sera appelée et transmise à un objet élément comme paramètre
Si vous regardez attentivement, vous verrez que lorsque le navigateur crée cet objet élément, il s'agit toujours du balisage html d'origine
1. Dans ng, le dom d'origine est généralement utilisé pour identifier l'élément de modèle, j'ai donc utilisé le nom tElem lors de la définition des paramètres de la fonction de compilation.
Une fois la fonction de compilation de la directive levelone exécutée, ng parcourra récursivement ses nœuds DOM en profondeur, puis répétera ces opérations aux niveaux deux et trois.
Post-lien
Avant de plonger dans la fonction de pré-lien, jetons un coup d'œil à la fonction de post-lien.
2. Si vous n'utilisez qu'une seule fonction de lien lors de la définition de l'instruction, alors ng traitera cette fonction comme un post-lien, nous devons donc d'abord discuter de cette fonction
Une fois que ng a parcouru tout le DOM et exécuté toutes les fonctions de compilation, il appelle la fonction post-link associée à l'envers
Le dom commence maintenant à inverser et à exécuter la fonction post-link. Par conséquent, cet appel inversé semblait un peu étrange auparavant, mais il est en fait parfaitement logique.
Lors de l'exécution d'une commande post-link contenant des sous-commandes, la règle post-link inversée peut garantir que le post-link de ses sous-commandes a déjà été exécuté.
Ainsi, lors de l'exécution de la fonction post-lien de l'instruction de niveau un, nous pouvons nous assurer que les post-liens des niveaux deux et trois ont effectivement été exécutés.
C'est pourquoi les gens pensent que le post-lien est l'endroit le plus sûr ou par défaut pour écrire une logique métier.
Mais pourquoi l'élément ici est-il différent de celui de la compilation ?
Une fois que ng appelle la fonction de compilation de l'instruction, il créera un objet instance d'élément de l'élément modèle et lui fournira un objet scope. Cette portée peut être une nouvelle instance, ou elle peut déjà exister, ou elle peut l'être. une sous-portée. Il peut également s'agir d'une portée indépendante, qui dépend entièrement de la valeur de l'attribut scope dans l'objet de définition d'instruction
Ainsi, lorsque la liaison se produit, cet élément d'instance et cet objet de portée sont déjà disponibles et sont transmis en tant que paramètres à la liste de paramètres de la fonction post-lien par ng.
1. Personnellement, j'utilise toujours le nom iElem pour définir les paramètres d'une fonction de lien, et il pointe vers l'instance de l'élément
Ainsi, l'objet paramètre d'élément de la fonction post-lien (pré-lien) est une instance d'élément plutôt qu'un élément de modèle.
Le résultat dans l'exemple ci-dessus est donc différent
Pré-lien
Lors de l'écriture d'une fonction post-lien, vous pouvez vous assurer que lorsque la fonction post-lien est exécutée, les fonctions post-lien de toutes ses instructions enfants ont déjà été exécutées.
Dans la plupart des cas, il peut faire mieux, nous l'utilisons donc généralement pour écrire des codes d'instructions.
Cependant, ng nous fournit un mécanisme de hook supplémentaire, qui est la fonction de pré-lien, qui garantit qu'un autre code est exécuté avant que les fonctions de post-lien de toutes les sous-instructions ne soient exécutées
.Cette phrase mérite une considération répétée
La fonction de pré-lien est garantie d'être exécutée avant le post-lien de l'instance d'élément et toutes ses sous-instructions sont exécutées.
Il est donc logique d'exécuter la fonction post-lien à l'envers, et il s'agit en soi de l'exécution séquentielle originale de la fonction pré-lien
Cela signifie également que la fonction de pré-lien s'exécute avant les fonctions de pré-lien de toutes ses sous-instructions, donc la raison complète est :
La fonction de pré-lien d'un élément est garantie d'être exécutée avant que le post-lien et le pré-lien de toutes ses sous-commandes soient exécutés. Voir la figure ci-dessous :
.Revue
Si nous regardons le résultat original ci-dessus, nous pouvons clairement reconnaître ce qui s'est passé :
// PHASE DE COMPILATION
// levelOne : la fonction de compilation est appelée sur le DOM d'origine
// levelTwo : la fonction de compilation est appelée sur le DOM d'origine
// levelThree : la fonction de compilation est appelée sur le DOM d'origine
// À PARTIR D'ICI, LES ÉLÉMENTS ONT ÉTÉ INSTANTIÉS ET
// SONT LIÉS À UNE PORTÉE
// (par exemple, NG-REPEAT aurait plusieurs instances)
// PHASE PRÉ-LIEN
// levelOne : la fonction de pré-lien est appelée sur l'instance d'élément
// levelTwo : la fonction de pré-lien est appelée sur l'instance d'élément
// levelThree : la fonction de pré-lien est appelée sur l'instance d'élément
// PHASE POST-LINK (Notez l'ordre inverse)
// levelThree : la fonction de lien de publication est appelée sur l'instance d'élément
// levelTwo : la fonction de lien de publication est appelée sur l'instance d'élément
// levelOne : la fonction de lien de publication est appelée sur l'instance d'élément
概要
回顾上面的分析我们可以描述一下这些函数的区别以及使用情况 :
Compile 函数
使用compile函数可以改变原始的dom (élément de modèle),在ng创建原始dom实例以及创建scope实例之前.
可以应用于当需要生成多个element实例,只有一个template element的情况,ng-repeat就是一个最好的例子,它就在是compile函数阶段改变原始的dom生成多个原始dom节点,然后Il s'agit d'un élément de compilation.的.
élément de modèle以及相关的属性是做为参数传递给compile函数的,不过这时候scope是不能用的 :
下面是函数样子:
// ...
};
Pré-lien 函数
Le pré-lien est utilisé pour la compilation, et le post-lien est post-lien.要执行之前.
scope对象以及element实例将会做为参数传递给pré-lien函数 :
下面是函数样子:
// ...
};
Post-lien 函数
使用post-link函数来执行业务逻辑,在这个阶段,它已经知道它所有的子指令已经编译完成并且pre-link以及post-link函数已经执行完成.
这就是被认为是最安全以及默认的编写业务逻辑代码的原因.
scope实例以及element实例做为参数传递给post-link函数 :
下面是函数样子:
// ...
};
Résumé
Vous devriez maintenant avoir une compréhension claire des différences entre les fonctions de compilation, de pré-lien et de post-lien.
Si ce n'est pas le cas et que vous êtes un développeur ng sérieux, alors je vous recommande fortement de relire cet article jusqu'à ce que vous le compreniez
Il est très important de comprendre ces concepts, qui peuvent vous aider à comprendre le fonctionnement des instructions natives de ng, et peuvent également vous aider à optimiser vos propres instructions personnalisées.
Si vous avez encore des questions, n'hésitez pas à ajouter vos questions dans les commentaires ci-dessous
J'analyserai les deux autres points de la directive à l'avenir :
1. Comment fonctionne la directive qui utilise l'attribut de transclusion
2. Comment les fonctions du contrôleur des instructions sont-elles liées ?
Merci !