Quando usar transclude 'true' e transclude 'elemento' em Angular?

176

Quando devo usar transclude: 'true'e quando transclude: 'element'? Não consigo encontrar nada transclude: 'element'nos documentos angulares, eles são bastante confusos.

Eu ficaria feliz se alguém pudesse explicar isso em linguagem simples. Qual é o benefício de cada opção? Qual é a diferença real entre eles?

Isto é o que eu encontrei:

transclude: true

Dentro de uma função de compilação, você pode manipular o DOM com a ajuda da função de vinculação de transclusão ou inserir o DOM transcluído no modelo usando a diretiva ngTransclude em qualquer marca HTML.

e

transclude: element

Isso inclui o elemento inteiro e uma função de vinculação de transclude é introduzida na função de compilação. Você não pode ter acesso ao escopo aqui porque o escopo ainda não foi criado. A função Compile cria uma função de link para a diretiva que tem acesso ao escopo e transcludeFn permite tocar no elemento clonado (que foi transcluído) para manipulação do DOM ou usar dados vinculados ao escopo nela. Para sua informação, isso é usado em ng-repeat e ng-switch.

LauroSkr
fonte

Respostas:

229

Da documentação do AngularJS sobre diretivas :

transclude- compilar o conteúdo do elemento e disponibilizá-lo para a diretiva. Normalmente usado com ngTransclude. A vantagem da transclusão é que a função de vinculação recebe uma função de transclusão que é pré-ligada ao escopo correto. Em uma configuração típica, o widget cria um escopo isolado, mas a transclusão não é uma criança, mas um irmão do escopo isolado. Isso possibilita que o widget tenha um estado privado e a transclusão seja vinculada ao escopo pai (pré-isolado).

true - transcluir o conteúdo da diretiva.

'element' - transcluir todo o elemento, incluindo quaisquer diretivas definidas com menor prioridade.

transclude: true

Então, digamos que você tenha uma diretiva chamada my-transclude-truedeclarada com a transclude: trueseguinte aparência:

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

Após a compilação e antes da vinculação, isso se torna:

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

O conteúdo (filhos) do my-transclude-truequal <span>{{ something }}</span> {{...é transcluído e está disponível para a diretiva.

transclude: 'elemento'

Se você tiver uma diretiva chamada my-transclude-elementdeclarada com transclude: 'element'essa aparência:

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

Após a compilação e antes da vinculação, isso se torna:

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

Aqui, todo o elemento, incluindo seus filhos, é transcluído e disponibilizado para a diretiva.

O que acontece após o link?

Depende da sua diretiva fazer o que for necessário com a função transclude. ngRepeatusa transclude: 'element'para que ele possa repetir todo o elemento e seus filhos quando o escopo for alterado. No entanto, se você apenas precisar substituir a tag e desejar reter seu conteúdo, poderá usar transclude: truea ngTranscludediretiva que faz isso por você.

sirhc
fonte
3
Eu meio que perdi a made available to the directivedeclaração. O elemento está sempre disponível para a diretiva. Você pode por favor elaborar nisso?
cara Mograbi
1
@guymograbi Essa frase pode fazer mais sentido como "disponibilizada para a diretiva por meio de uma função pré-vinculada ao escopo correto ".
31414 Michelle Michelle Tilley
Como uma unidade testaria uma diretiva com transclude igual a 'elemento'? Atualmente, estou lutando com esse problema. Não consigo acessar o elemento depois que ele foi transcluído.
Chester Rivas
33

Quando definida como true, a diretiva excluirá o conteúdo original, mas disponibilizará para reinserção no seu modelo por meio de uma diretiva chamada ng-transclude.

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


<div directive-name>world</div>

renderização do navegador: "Olá, mundo."

André Dion
fonte
23
Isso não responder à pergunta em tudo (que era sobre a diferença entre transclude: truee transclude: element)
Jasper
1
Também o que seria interessante é o que marca a DOM browser posteriores à directiva, não é o que lê ...
kontur
8

A melhor maneira de pensar sobre a transclusão é um porta-retrato.Um porta-retrato tem seu próprio design e um espaço para adicionar a imagem.Podemos decidir qual imagem será inserida nela.insira a descrição da imagem aqui

Quando se trata de angular, temos algum tipo de controlador com seu escopo e, dentro disso, colocaremos uma diretiva que suporta a transclusão. Esta diretiva terá sua própria exibição e funcionalidade. Na diretiva não traduzida, o conteúdo dentro da diretiva é decidido pela própria diretiva, mas com a transclusão, assim como uma moldura, podemos decidir o que estará dentro da diretiva.

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


    }

});

Conteúdo dentro da diretiva

<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>

Diretiva de Chamada

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

Exemplo

Code-EZ
fonte
Ainda não entendi a transclude, você pode ter algum programa simples para ilustrar isso?
Raja