web-dev-qa-db-fra.com

Comprendre l’option transclude de la définition de directive?

Je pense que c'est l'un des concepts les plus difficiles à comprendre pour moi avec la directive angularjs.

Le document de http://docs.angularjs.org/guide/directive dit:

transclude - compile le contenu de l'élément et le met à la 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'isolement, mais la transclusion n'est pas un enfant, mais un frère de l'étendue d'isolement. Cela permet au widget d'avoir un état privé et la transclusion d'être liée à la portée parent (pré-isolée).

  • true - transclude le contenu de la directive.
  • 'élément' - comprend tout l'élément, y compris les directives définies avec une priorité inférieure.

Il indique transclude généralement utilisé avec ngTransclude. Mais l'exemple de la doc de ngTransclude n'utilise pas du tout la directive ngTransclude.

Je voudrais quelques bons exemples pour m'aider à comprendre cela. Pourquoi en avons-nous besoin? Qu'est-ce que ça résout? Comment l'utiliser?

188
Freewind

Considérons une directive appelée myDirective dans un élément, et cet élément contient un autre contenu, disons:

<div my-directive>
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Si myDirective utilise un modèle, vous verrez que le contenu de <div my-directive> sera remplacé par votre modèle de directive. Donc avoir:

app.directive('myDirective', function(){
    return{
        template: '<div class="something"> This is my directive content</div>'
    }
});

entraînera ce rendu:

<div class="something"> This is my directive content</div> 

Notez que le contenu de votre élément d'origine <div my-directive> sera perdu (ou mieux, remplacé). Alors, dites au revoir à ces amis:

<button>some button</button>
<a href="#">and a link</a>

Alors, si vous voulez conserver votre <button>... et <a href>... dans le DOM? Vous aurez besoin de quelque chose appelé transclusion. Le concept est assez simple: Incluez le contenu d'un endroit à un autre . Alors maintenant, votre directive ressemblera à quelque chose comme ça:

app.directive('myDirective', function(){
    return{
        transclude: true,
        template: '<div class="something"> This is my directive content</div> <ng-transclude></ng-transclude>'
    }
});

Cela rendrait:

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>. 

En conclusion, vous utilisez essentiellement transclude lorsque vous souhaitez conserver le contenu d'un élément lorsque vous utilisez une directive.

Mon exemple de code est ici . Vous pourriez également bénéficier de regarder this .

500
odiseo

Je pense qu'il est important de mentionner les changements dans le comportement ci-dessus dans la nouvelle version d'AngularJS. J'ai passé une heure à essayer d'obtenir les résultats ci-dessus avec Angular 1.2.10.

Le contenu de l'élément avec ng-transclude n'est pas ajouté mais est complètement remplacé.

Ainsi, dans l'exemple ci-dessus, ce que vous obtiendriez avec 'transclude' serait:

<div class="something">
    <button>some button</button>
    <a href="#">and a link</a>
</div>

et pas

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Merci.

75
TechExplorer

Ce que TechExplorer dit est vrai, mais vous pouvez avoir les deux contenus en incluant dans votre modèle une simple balise de conteneur (comme div ou span) avec l’attribut ng-transclude. Cela signifie que le code suivant dans votre modèle devrait inclure tout le contenu

<div class="something"> This is my directive content <div class="something" ng-transclude></div></div>
36
goulpan

De Wiki:

"En informatique, la transclusion est l’inclusion d’une partie ou de la totalité d’un document électronique dans un ou plusieurs autres documents par référence."

J'aimerais ajouter une autre utilisation à la transclusion, à savoir qu'elle modifie l'ordre d'exécution des fonctions de compilation et de liaison des directives parent et enfant. Cela peut être utile lorsque vous voulez compiler le DOM enfant avant le DOM parent en tant que DOM parent peut-être dépendre du DOM enfant. Cet article va plus en profondeur et le clarifie très bien!

http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives-part-2-transclusion/

5
Samir Alajmovic

Le documentation mise à jour sur AngularJS 1.6.6 a maintenant une meilleure explication.

Transclude est utilisé pour créer une directive qui enveloppe d'autres éléments

Parfois, il est souhaitable de pouvoir transmettre un modèle entier plutôt qu'une chaîne ou un objet. Disons que nous voulons créer un composant "boîte de dialogue". La boîte de dialogue doit pouvoir envelopper tout contenu arbitraire.

Pour ce faire, nous devons utiliser l'option transclude . Reportez-vous à l'exemple ci-dessous.


script.js

angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});

index.html

<div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>

my-dialog.html

<div class="alert" ng-transclude></div>

Sortie compilée

<div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>

Transclude fait en sorte que le contenu d'une directive avec cette option ait accès à la portée à l'extérieur de la directive plutôt qu'à l'intérieur.

Ceci est illustré dans l'exemple précédent. Notez que nous avons ajouté une fonction de lien dans script.js qui redéfinit le nom en tant que Jeff. D'habitude, on s'attendrait à ce que {{name}} soit Jeff. Cependant, nous voyons dans cet exemple que la liaison {{name}} est toujours Tobias.

Meilleure pratique : utilisez uniquement transclude: true lorsque vous souhaitez créer une directive qui englobe un contenu arbitraire.

3
Arthur S

transclude: true signifie ajouter tous les éléments définis dans votre directive avec l'élément template de votre directive.

si transclude: false, ces éléments ne sont pas inclus dans votre code HTML final de directive. Seul le modèle de directive est rendu.

transclude: element signifie que votre modèle de directive n'est pas utilisé. Seuls les éléments définis dans votre directive sont rendus au format HTML.

lorsque vous définissez votre directive, il devrait être limité à E et lorsque vous l'ajoutez à la page, puis

<my-directive><elements><my-directive>
<elements> is like <p>gratitude</p>
what i am talking about.
0
dev verma