Quand utiliser transclude 'true' et transclude 'element' dans Angular?

176

Quand dois-je utiliser transclude: 'true'et quand transclude: 'element'? Je ne trouve rien transclude: 'element'dans les documents angulaires, ils sont assez déroutants.

Je serais heureux si quelqu'un pouvait expliquer cela dans un langage simple. Quel est l'avantage de chaque option? Quelle est la vraie différence entre eux?

Voici ce que j'ai trouvé:

transclude: true

Dans une fonction de compilation, vous pouvez manipuler le DOM à l'aide de la fonction de liaison transclude ou vous pouvez insérer le DOM transclu dans le modèle en utilisant la directive ngTransclude sur n'importe quelle balise HTML.

et

transclude: element

Cela englobe tout l'élément et une fonction de liaison transclude est introduite dans la fonction de compilation. Vous ne pouvez pas avoir accès à l'étendue ici car l'étendue n'est pas encore créée. La fonction de compilation crée une fonction de lien pour la directive qui a accès à la portée et transcludeFn vous permet de toucher l'élément cloné (qui a été transclus) pour la manipulation DOM ou d'utiliser les données liées à la portée. Pour votre information, ceci est utilisé dans ng-repeat et ng-switch.

LauroSkr
la source

Réponses:

229

À partir de la documentation AngularJS sur les directives :

transclude- compiler le contenu de l'élément et le mettre à disposition de la directive. Généralement utilisé avec ngTransclude. L'avantage de la transclusion est que la fonction de liaison reçoit une fonction de transclusion qui est pré-liée à la portée correcte. Dans une configuration typique, le widget crée une étendue d'isolat, mais la transclusion n'est pas un enfant, mais un frère de l'étendue d'isolat. Cela permet au widget d'avoir un état privé et à la transclusion d'être liée à la portée parent (pré-isoler).

true - transclure le contenu de la directive.

'element' - englober tout l'élément, y compris les directives définies à une priorité inférieure.

transclude: vrai

Disons que vous avez une directive appelée my-transclude-truedéclarée avec transclude: truequi ressemble à ceci:

<div>
  <my-transclude-true>
    <span>{{ something }}</span>
    {{ otherThing }}
  </my-transclude-true>
</div>

Après la compilation et avant la liaison, cela devient:

<div>
  <my-transclude-true>
    <!-- transcluded -->
  </my-transclude-true>
</div>

Le contenu (enfants) my-transclude-truedont est <span>{{ something }}</span> {{..., est transclus et disponible pour la directive.

transclude: 'élément'

Si vous avez une directive appelée my-transclude-elementdéclarée avec transclude: 'element'qui ressemble à ceci:

<div>
  <my-transclude-element>
    <span>{{ something }}</span>
    {{ otherThing }}
  </my-transclude-element>
</div>

Après la compilation et avant la liaison, cela devient:

<div>
   <!-- transcluded -->
</div>

Ici, tout l'élément, y compris ses enfants, est transcrit et mis à la disposition de la directive.

Que se passe-t-il après la liaison?

C'est à votre directive de faire ce qu'elle doit faire avec la fonction transclude. ngRepeatutilise transclude: 'element'afin qu'il puisse répéter tout l'élément et ses enfants lorsque la portée change. Cependant, si vous avez seulement besoin de remplacer la balise et que vous souhaitez conserver son contenu, vous pouvez utiliser transclude: trueavec la ngTranscludedirective qui le fait pour vous.

sirhc
la source
3
J'ai un peu manqué la made available to the directivedéclaration. L'élément est toujours disponible pour la directive. Pourriez-vous nous expliquer cela?
guy mograbi
1
@guymograbi Cette phrase peut avoir plus de sens car "mise à la disposition de la directive via une fonction pré-liée à la bonne portée ".
Michelle Tilley
Comment une unité testerait-elle une directive avec transclude égale à «élément»? Je suis actuellement aux prises avec ce problème. Je n'arrive pas à accéder à l'élément une fois qu'il a été transclus.
Chester Rivas
33

Lorsqu'elle est définie sur true, la directive supprimera le contenu d'origine, mais le rendra disponible pour une réinsertion dans votre modèle via une directive appelée ng-transclude.

appModule.directive('directiveName', function() {
    return {
      template: '<div>Hello there <span ng-transclude></span></div>',
      transclude: true
    };
});


<div directive-name>world</div>

rendu du navigateur: "Bonjour le monde."

André Dion
la source
23
Cela ne répond pas du tout à la question (qui concernait la différence entre transclude: trueet transclude: element)
Jasper
1
Ce qui serait également intéressant, ce sont les balises que le DOM du navigateur a après la directive, pas ce qu'il lit ...
kontur
8

La meilleure façon de penser à la transclusion est un cadre photo. Un cadre photo a son propre design et un espace pour l'ajout de l'image. Nous pouvons décider quelle image va y entrer.entrez la description de l'image ici

En ce qui concerne angulaire, nous avons une sorte de contrôleur avec sa portée et à l'intérieur de cela, nous placerons une directive qui prend en charge la transclusion. Cette directive aura son propre affichage et ses propres fonctionnalités. Dans la directive non transludée, le contenu à l'intérieur de la directive est décidé par la directive elle-même, mais avec la transclusion, tout comme un cadre photo, nous pouvons décider de ce qui sera à l'intérieur de la directive.

angular.module("app").directive('myFrame', function () {
    return {
        restrict: 'E',
        templateUrl:"frame.html",
        controller:function($scope){
          $scope.hidden=false;
          $scope.close=function(){
            $scope.hidden=true;

          }
        },
        transclude:true


    }

});

Contenu à l'intérieur de la directive

<div class="well" style="width:350px;" ng-hide="hidden">

  <div style="float:right;margin-top:-15px">
    <i class="glyphicon glyphicon-remove" ng-click="close()" style="cursor:pointer"></i> 
  </div>
  <div ng-transclude>
    /*frame content goes here*/
  </div>
</div>

Directive d'appel

<body ng-controller="appController">
    <my-frame>
      <span>My Frame content</span>
    </my-frame>
  </body>

Exemple

Code-EZ
la source
Je n'ai toujours pas compris le transclude, pouvez-vous avoir un programme simple pour illustrer cela?
Raja