Angular: NgTemplate

Henrique Custódia
criciumadev
Published in
3 min readAug 16, 2017

Criando componentes customizáveis

Desde que comecei a produzir componentes reutilizáveis com Angular2+, sempre procurei faze-los o mais customizáveis possível utilizando Inputs e ng-content. Porém nem sempre conseguia, pois para alguns componentes não é suficiente simplesmente encapsular um conteúdo dentro de uma estrutura pronta como ng-content faz, há casos em que o conteúdo do componente deve receber dados do próprio componente para que possa renderizar algo mais interessante.

Fiz algumas pesquisas para procurar soluções que me dessem mais flexibilidade para usar templates customizáveis nos componentes e encontrei alguns exemplos no stackoverflow de como usar ng-template para atender essa necessidade.

Legal e como se usa isso?

Para transmitir bem o que estou tentado dizer, vamos criar aos poucos um componente simples que possa renderizar de forma customizada alguns dados.

O Componente abaixo simplesmente renderiza uma lista de nomes usando um array names.

Agora vamos fazer o componente permitir receber um template customizável para podermos mostrar os nomes do array names como desejarmos.

Apenas para explicar o está acontencendo no componente:

O Decorator @ContentChild buscará uma referência de TemplateRef no conteúdo do componente e então injetará a referência do template no ng-template que está no template do componente.

Agora vamos usar o componente com o template customizável para renderizar os nomes:

Note que usamos a instrução let- para criar uma referência no escopo do template, o que nos permite renderizar todos os nomes da maneira que desejarmos.

Hmm mas se nem sempre quiser um template customizável?

Digamos agora que se por acaso quem for usar o componente MyComponent, não deseje usar um template customizável mas sim apenas mostrar da forma nativa os nomes que estão em MyComponent. Nesse caso precisaremos criar um template interno para que quando não houver um template customizável disponível o componente utilize o interno por padrão.

Dessa forma para usar o componente sem template customizável seria simplesmente assim:

Preciso sempre selecionar a propriedade do contexto no template?

Se desejar, você pode fazer com que o objeto que está sendo enviado na diretiva [ngOutletContext] seja acessado diretamente sem precisar usar a syntax:

let-<ref-name>=”<propName>”.

Sendo assim, você precisará dizer a diretiva [ngOutletContext] que esse objeto de contexto deve ser acessado implicitamente usando a propriedade $implicit, da seguinte forma:

Assim para consumir os dados em um template customizável apenas faríamos dessa forma:

Note que data é apenas uma referência no escopo do template para o objeto que passamos em [ngOutletContext]:

[ngOutletContext]=”{ $implicit: { names: names } }”

Essa abordagem de dados implícitos é bem útil para objetos de contexto grandes.

Conclusão

Usar ng-template para trabalhar com templates customizáveis nos seus componentes pode ser um caminho para criar componentes menos desacoplados e dinâmicos. E claro, mais poderosos.

Se esse artigo ajudou você de alguma forma não deixe de compartilhar e recomendar, garanto que existem muitas pessoas com as mesmas necessidades!

Obrigado por ler e não deixe de seguir a Code Dimension.

Até a próxima! :)

--

--