JS angulaire :Quel est le besoin de la fonction de lien de la directive alors que nous avions déjà le contrôleur de la directive avec une portée ?

StackOverflow https://stackoverflow.com//questions/20018507

Question

Je dois effectuer certaines opérations sur la portée et le modèle.Il semble que je puisse le faire soit dans link fonction ou le controller fonction (puisque les deux ont accès à la portée).

Quand dois-je utiliser link fonction et pas le contrôleur ?

angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}

Aussi, je comprends que link est le monde non angulaire.Donc, je peux utiliser $watch, $digest et $apply.

Quelle est la signification du link fonction, alors qu'on avait déjà un contrôleur ?

Était-ce utile?

La solution

Après mon initial lutter avec le link et controller fonctions et en lisant beaucoup à leur sujet, je pense que j'ai maintenant la réponse.

Tout d'abord, permettons comprendre,

Comment fonctionnent les directives angulaires en un mot :

  • Nous commençons par un modèle (sous forme de chaîne ou chargé dans une chaîne)

    var templateString = '<div my-directive>{{5 + 10}}</div>';

  • Maintenant ça templateString est enveloppé comme un élément angulaire

    var el = angular.element(templateString);

  • Avec el, maintenant nous le compilons avec $compile pour récupérer le lien fonction.

    var l = $compile(el)

    Voici ce qui se passe,

    • $compile parcourt l'ensemble du modèle et collecte toutes les directives qu'il reconnaît.
    • Toutes les directives découvertes sont compilé de manière récursive et leur link les fonctions sont collectées.
    • Ensuite, tout le link les fonctions sont enveloppées dans un nouveau link fonction et renvoyé comme l.
  • Enfin, nous fournissons scope fonction à cela l (lien) fonction qui exécute en outre les fonctions de lien encapsulées avec ce scope et leurs éléments correspondants.

    l(scope)

  • Cela ajoute le template en tant que nouveau nœud du DOM et invoque controller qui ajoute ses montres au portée qui est partagé avec le modèle dans DOM.

enter image description here

Comparant compiler contre lien contre manette :

  • Chaque directive est compilé une seule fois et lien la fonction est conservée pour être réutilisée.Par conséquent, s'il y a quelque chose d'applicable à toutes les instances d'une directive, il doit être exécuté dans le fichier de la directive. compile fonction.

  • Maintenant, après compilation, nous avons link fonction qui est exécutée lors de la fixation du modèle au DOMAINE.Nous effectuons donc tout ce qui est spécifique à chaque instance de la directive.Par exemple : joindre des événements, mutation du modèle en fonction de la portée, etc.

  • Finalement, le manette est censé être disponible pour être actif et réactif pendant que la directive travaille sur le DOM (après s'être attaché).Donc:

    (1) Après avoir configuré la vue[V] (c'est à dire.modèle) avec lien. $scope est notre [M] et $controller est notre [C] dans MVC

    (2) Profitez du 2 voies liaison avec $portée en mettant en place des veilles.

    (3) $scope les montres devraient être ajoutées dans le contrôleur puisque c'est ce qui surveille le modèle pendant l'exécution.

    (4) Enfin, controller est également utilisé pour pouvoir communiquer entre les directives associées.(Comme myTabs exemple dans https://docs.angularjs.org/guide/directive)

    (5) C'est vrai qu'on aurait pu faire tout ça dans le link fonctionner aussi mais c'est à propos de séparation des préoccupations.

Nous avons donc finalement ce qui suit qui s'adapte parfaitement à toutes les pièces :

enter image description here

Autres conseils

Pourquoi les contrôleurs sont nécessaires

La différence entre link et controller entre en jeu lorsque vous souhaitez imbriquer des directives dans votre DOM et exposer les fonctions API de la directive parent à celles imbriquées.

Du documents:

Meilleur entrainement:utilisez le contrôleur lorsque vous souhaitez exposer une API à d'autres directives.Sinon, utilisez le lien.

Disons que vous voulez avoir deux directives my-form et my-text-input et tu veux my-text-input directive à apparaître uniquement à l'intérieur my-form et nulle part ailleurs.

Dans ce cas, direz-vous en définissant la directive my-text-input que c'est a besoin un contrôleur du parent élément DOM utilisant le require argument, comme ça: require: '^myForm'.Maintenant, le contrôleur de l'élément parent sera injected dans le link fonctionner comme quatrième argument, après $scope, element, attributes.Vous pouvez appeler des fonctions sur ce contrôleur et communiquer avec la directive parent.

De plus, si un tel contrôleur n’est pas trouvé, une erreur sera générée.

Pourquoi utiliser le lien

Il n'est pas vraiment nécessaire d'utiliser le link fonction si l'on définit la controller depuis le $scope est disponible sur le controller.De plus, tout en définissant à la fois link et controller, il faut faire attention à l'ordre d'invocation des deux (controller est exécuté auparavant).

Cependant, conformément au Voie angulaire, la plupart des manipulations DOM et des liaisons bidirectionnelles utilisant $watchers se fait généralement dans le link fonctionner tandis que l'API pour les enfants et $scope la manipulation se fait dans le controller.Ce n'est pas une règle absolue, mais cela rendra le code plus modulaire et aidera à séparer les problèmes (le contrôleur maintiendra le directive l'état et link fonction maintiendra le DOM + reliures extérieures).

Le controller fonction/objet représente un modèle-vue-contrôleur d'abstraction (MVC).Bien qu'il n'y ait rien de nouveau à écrire sur MVC, c'est toujours l'avantage le plus significatif d'angular :divisez les préoccupations en morceaux plus petits.Et voilà, rien de plus, donc si vous avez besoin de réagir Model changements provenant de View le Controller est le droit personne pour faire ce travail.

L'histoire de link la fonction est différente, elle vient d'un point de vue différent de celui de MVC.Et c'est vraiment essentiel, dès lors que l'on veut dépasser les frontières d'un controller/model/view (modèle).

Commençons par les paramètres qui sont passés dans le link fonction:

function link(scope, element, attrs) {
  • portée est un objet de portée angulaire.
  • élément est l'élément enveloppé dans jqLite auquel cette directive correspond.
  • attributs est un objet avec les noms d'attributs normalisés et leurs valeurs correspondantes.

Mettre le link dans le contexte, nous devons mentionner que toutes les directives passent par ces étapes de processus d'initialisation : Compiler, Lien.Un extrait de Brad Green et Shyam Seshadri livrent Angular JS:

Phase de compilation (une sœur de link, mentionnons-la ici pour y voir clair) :

Dans cette phase, Angular parcourt le DOM pour identifier toutes les directives enregistrées dans le modèle.Pour chaque directive, il transforme ensuite le DOM en fonction des règles de la directive (modèle, remplacer, transcluder, etc.), et appelle la fonction de compilation s'il existe.Le résultat est une fonction de modèle compilée,

Phase de liaison:

Pour rendre la vue dynamique, Angular exécute alors une fonction de liaison pour chaque directive.Les fonctions de liaison crée généralement des auditeurs sur le DOM ou le modèle.Ces auditeurs gardent la vue et le modèle de synchronisation à tout moment.

Un bel exemple d'utilisation du link on peut le trouver ici : Création de directives personnalisées.Voir l'exemple : Créer une directive qui manipule le DOM, qui insère une "date-heure" dans la page, actualisée toutes les secondes.

Juste un très court extrait de cela riche source ci-dessus, montrant la véritable manipulation avec DOM.Il existe une fonction liée au service $timeout, et elle est également effacée dans son destructeur appeler pour éviter les fuites de mémoire

.directive('myCurrentTime', function($timeout, dateFilter) {

 function link(scope, element, attrs) {

 ...

 // the not MVC job must be done
 function updateTime() {
   element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
 }

 function scheduleUpdate() {
   // save the timeoutId for canceling
   timeoutId = $timeout(function() {
     updateTime(); // update DOM
     scheduleUpdate(); // schedule the next update
   }, 1000);
 }

 element.on('$destroy', function() {
   $timeout.cancel(timeoutId);
 });

 ...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top