Question Lien vs compiler vs contrôleur


Lorsque vous créez une directive, vous pouvez mettre du code dans le compilateur, la fonction de lien ou le contrôleur.

Dans les docs, ils expliquent que:

  • fonction de compilation et de liaison sont utilisés dans différentes phases de l'angulaire cycle
  • les contrôleurs sont partagés entre les directives

Cependant, pour moi, ce n'est pas clair, quel type de code devrait aller où.

Par exemple, est-ce que je peux créer des fonctions dans la compilation et les attacher à la portée dans link ou seulement attacher des fonctions à la portée dans le contrôleur?

Comment les contrôleurs sont-ils partagés entre les directives, si chaque directive peut avoir son propre contrôleur? Les contrôleurs sont-ils réellement partagés ou s'agit-il simplement des propriétés de la portée?


508
2018-03-28 07:48


origine


Réponses:


Compiler : 

C'est la phase où Angular compile réellement votre directive. Cette fonction de compilation est appelée une seule fois pour chaque référence à la directive donnée. Par exemple, dites que vous utilisez la directive ng-repeat. ng-repeat devra rechercher l'élément auquel il est attaché, extraire le fragment html auquel il est attaché et créer une fonction template.

Si vous avez utilisé HandleBars, des modèles de soulignement ou l'équivalent, c'est comme si vous compiliez leurs modèles pour extraire une fonction de modèle. Pour cette fonction de modèle, vous transmettez des données et la valeur renvoyée par cette fonction est le code HTML contenant les données aux bons endroits.

La phase de compilation est cette étape dans Angular qui retourne la fonction template. Cette fonction de gabarit en angulaire s'appelle la fonction de liaison.

Phase de liaison: 

La phase de liaison est l'endroit où vous attachez les données ($ scope) à la fonction de liaison et vous devez retourner le fichier HTML lié. Puisque la directive spécifie également où va ce code html ou ce qu'il change, il est déjà bon d'y aller. C'est la fonction où vous voulez faire des changements au html lié, c'est-à-dire le html auquel les données sont déjà attachées. En angulaire si vous écrivez du code dans la fonction de liaison, c'est généralement la fonction post-lien (par défaut). C'est une sorte de rappel qui est appelé après que la fonction de liaison a lié les données avec le modèle.

Manette :

Le contrôleur est un endroit où vous mettez dans une certaine logique spécifique à la directive. Cette logique peut également entrer dans la fonction de liaison, mais vous devrez alors mettre cette logique sur la portée pour la rendre «partageable». Le problème avec cela est que vous corrompriez alors la portée avec vos trucs de directives, ce qui n'est pas vraiment quelque chose qui est attendu. Alors, quelle est l'alternative si deux directives veulent se parler / coopérer les unes avec les autres? Bien sûr, vous pouvez mettre toute cette logique dans un service et ensuite faire en sorte que ces deux directives dépendent de ce service, mais cela ne fait qu'apporter une dépendance supplémentaire. L'alternative est de fournir un contrôleur pour cette portée (généralement isoler la portée?) Et ensuite ce contrôleur est injecté dans une autre directive lorsque cette directive "nécessite" l'autre. Voir les onglets et les volets sur la première page de angularjs.org pour un exemple.


454
2018-03-28 11:58



Je voulais également ajouter ce que le livre O'Reily AngularJS de l'équipe Google a à dire:

Contrôleur - Créez un contrôleur qui publie une API pour communiquer entre les directives. Un bon exemple est Directive à la Directive Communication

Lien: modifiez par programme les instances d'éléments DOM résultantes, ajoutez des écouteurs d'événement et configurez la liaison de données.

Compiler - Modifiez par programme le modèle DOM pour les entités sur les copies d'une directive, comme lorsqu'il est utilisé dans ng-repeat. Votre fonction de compilation peut également renvoyer des fonctions de lien pour modifier les instances d'éléments résultantes.


95
2018-06-04 19:59



UNE directive vous permet d'étendre le vocabulaire HTML d'une manière déclarative pour la création de composants Web. le ng-app attribut est une directive, est donc ng-controller et tout le ng- prefixed attributes. Les directives peuvent être attributes, tags ou même class  names, comments.

Comment naissent les directives (compilation et instantiation)

Compiler: Nous allons utiliser le compile fonction à la fois manipulate le DOM avant qu'il ne soit rendu et renvoyer un link fonction (qui s'occupera du lien pour nous). C'est aussi l'endroit pour mettre toutes les méthodes qui doivent être partagées avec tous les instances de cette directive.

lien: Nous allons utiliser le link Fonction pour enregistrer tous les écouteurs sur un élément DOM spécifique (qui est cloné à partir du modèle) et configurer nos liaisons à la page.

Si défini dans le compile() fonction qu'ils auraient seulement été mis une fois (ce qui est souvent ce que vous voulez). Si défini dans le link() fonction qu'ils seraient fixés à chaque fois que l'élément HTML est lié à des données dans le  objet.

<div ng-repeat="i in [0,1,2]">
    <simple>
        <div>Inner content</div>
    </simple>
</div>

app.directive("simple", function(){
   return {
     restrict: "EA",
     transclude:true,
     template:"<div>{{label}}<div ng-transclude></div></div>",        
     compile: function(element, attributes){  
     return {
             pre: function(scope, element, attributes, controller, transcludeFn){

             },
             post: function(scope, element, attributes, controller, transcludeFn){

             }
         }
     },
     controller: function($scope){

     }
   };
});

Compile fonction renvoie le pre et post fonction de lien. Dans la fonction pré-lien, nous avons le modèle d'instance et aussi la portée de la controller, mais le modèle n'est pas lié à la portée et n'a toujours pas de contenu transcrit.

Post La fonction lien est l'endroit où le lien post est la dernière fonction à exécuter. Maintenant le transclusion est complet, the template is linked to a scope, et le view will update with data bound values after the next digest cycle. le link option est juste un raccourci pour mettre en place un post-link fonction.

manette: Le contrôleur de la directive peut être passé à une autre phase de liaison / compilation de la directive. Il peut être injecté dans d'autres guides comme moyen de communication inter-directive.

Vous devez spécifier le nom de la directive à exiger - Il doit être lié au même élément ou à son parent. Le nom peut être préfixé avec:

? – Will not raise any error if a mentioned directive does not exist.
^ – Will look for the directive on parent elements, if not available on the same element.

Utiliser un crochet carré [‘directive1′, ‘directive2′, ‘directive3′] exiger plusieurs contrôleurs de directives.

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope, $element) {
});

app.directive('parentDirective', function() {
  return {
    restrict: 'E',
    template: '<child-directive></child-directive>',
    controller: function($scope, $element){
      this.variable = "Hi Vinothbabu"
    }
  }
});

app.directive('childDirective', function() {
  return {
    restrict:  'E',
    template: '<h1>I am child</h1>',
    replace: true,
    require: '^parentDirective',
    link: function($scope, $element, attr, parentDirectCtrl){
      //you now have access to parentDirectCtrl.variable
    }
  }
});

45
2017-09-29 14:07



En outre, une bonne raison d'utiliser un contrôleur par rapport à une fonction de liaison (puisqu'ils ont tous les deux accès à scope, element et attrs) est que vous pouvez transmettre n'importe quel service ou dépendance disponible dans un contrôleur (et dans n'importe quel ordre), vous ne pouvez pas faire cela avec la fonction de lien. Notez les différentes signatures:

controller: function($scope, $exceptionHandler, $attr, $element, $parse, $myOtherService, someCrazyDependency) {...

contre.

link: function(scope, element, attrs) {... //no services allowed

10
2017-11-07 15:47



c'est un bon échantillon pour comprendre les phases de la directive http://codepen.io/anon/pen/oXMdBQ?editors=101

var app = angular.module('myapp', [])

app.directive('slngStylePrelink', function() {
    return {
        scope: {
            drctvName: '@'
        },
        controller: function($scope) {
            console.log('controller for ', $scope.drctvName);
        },
        compile: function(element, attr) {
            console.log("compile for ", attr.name)
            return {
                post: function($scope, element, attr) {
                    console.log('post link for ', attr.name)
                },
                pre: function($scope, element, attr) {
                    $scope.element = element;
                    console.log('pre link for ', attr.name)
                        // from angular.js 1.4.1
                    function ngStyleWatchAction(newStyles, oldStyles) {
                        if (oldStyles && (newStyles !== oldStyles)) {
                            forEach(oldStyles, function(val, style) {
                                element.css(style, '');
                            });
                        }
                        if (newStyles) element.css(newStyles);
                    }

                    $scope.$watch(attr.slngStylePrelink, ngStyleWatchAction, true);

                    // Run immediately, because the watcher's first run is async
                    ngStyleWatchAction($scope.$eval(attr.slngStylePrelink));
                }
            };
        }
    };
});

html

<body ng-app="myapp">
    <div slng-style-prelink="{height:'500px'}" drctv-name='parent' style="border:1px solid" name="parent">
        <div slng-style-prelink="{height:'50%'}" drctv-name='child' style="border:1px solid red" name='child'>
        </div>
    </div>
</body>

9
2017-07-18 15:28



  • compiler: utilisé lorsque nous devons modifier un modèle de directive, comme ajouter une nouvelle expression, ajouter une autre directive dans cette directive
  • manette: utilisé lorsque nous avons besoin de partager / réutiliser les données $ scope
  • lien: c'est une fonction utilisée lorsque nous devons attacher un gestionnaire d'événements ou manipuler DOM.

2
2018-06-22 14:50