Ao criar novos componentes ao desenvolver no Angular, você se esforça para criá-los de forma que eles possam ser reutilizados várias vezes. Assim como no desenvolvimento de software, um programador se esforça para tornar seu código o mais reutilizável possível. Ao mesmo tempo, quero ter componentes flexíveis, mas não muito complexos.

Como regra, os componentes precisam ser feitos o mais estúpido possível, para que seja mais fácil manter e testar. Mas, ao mesmo tempo, eles são personalizáveis e flexíveis, para que você possa reutilizá-los muitas vezes e não se envolver em componentes de clonagem que são semelhantes visual e funcionalmente, mas ainda diferem em algo. Ou não adicione vários parâmetros aos componentes, com base nos quais habilitar ou desabilitar qualquer comportamento do componente, mas que de fato serão usados em 1 em cada 100 casos.
Criar um submarino, que deve afundar até o fundo do mar azul sem risco para a vida da tripulação e modificá-lo antes de voar pelo céu azul não é uma tarefa fácil.
Um componente angular é a menor unidade da interface do usuário que deve executar uma tarefa simples e nada mais. Criar componentes para todas as ocasiões é uma prática ruim. Portanto, você precisa encontrar um compromisso entre flexibilidade e simplicidade.
Suponha que você deseje criar um componente que consiste em algum tipo de wrapper, dentro do qual existe um cabeçalho, algum tipo de opção e algum conteúdo embaixo deles. Algo assim:

Todo o componente, que será chamado de widget, é destacado em verde. A opção do cabeçalho é destacada em vermelho e o conteúdo é destacado em azul. Angular é uma estrutura incrivelmente poderosa; criar um componente semelhante ao da imagem é uma tarefa muito trivial para Angular.

Mas e se esse componente for mais flexível, por exemplo, para que o conteúdo seja alterado dependendo dos parâmetros do componente do widget?
Você pode resolver a representação externa do conteúdo com base no parâmetro widget, por exemplo, usando a
diretiva estrutural
ngIf . Você pode alternar entre diferentes visões. E se houver muitos envios, você poderá usar outra
diretiva estrutural do
ngSwitch .

E se visualizações diferentes responderem de maneira diferente às ações do usuário? Em seguida, o código do componente também terá várias instruções condicionais. Mas o código, no qual existem muitas instruções condicionais, com o tempo torna-se difícil manter, corrigir erros ou expandir a funcionalidade ...
Você pode criar um componente de widget de forma a receber qualquer conteúdo, mas ao mesmo tempo lança os valores selecionados do painel de filtro nos componentes da área de conteúdo. E também gostaria de poder encaminhar parâmetros do componente pai do widget para o conteúdo, sem afetar o próprio componente do widget. Para resolver esse problema, você pode usar a maravilhosa diretiva
ngTemplateOutlet , que permitirá "resolver" a representação visual do componente. Para informações adicionais, você pode consultar a
documentação , embora, na minha opinião, todo o seu poder não seja mostrado lá.
Nesse caso, o componente do widget pode ser representado da seguinte maneira:
… <div class="widget__content"> <ng-container *ngTemplateOutlet="WidgetContentTemplate || DefaultWidgetContentTemplate; context: { post: SelectedPost }"> </ng-container> </div> <ng-template #DefaultWidgetContentTemplate> <div>[ ]</div> </ng-template> …
A diretiva ngTemplateOutlet aceita um objeto TemplateRef que é lido no componente usando @ContentChild. Para fazer isso, você precisa criar uma diretiva simples. Aqui está o código dela:
Os parâmetros da opção de widget podem ser passados para o conteúdo usando o objeto de contexto. Para que os parâmetros do contexto sejam lidos corretamente pelo componente, é necessário no componente pai, no nosso caso é AppComponent, não se esqueça de descrevê-los da seguinte forma:
<app-widget-component Title=" ( )"> <ng-template appWidgetContentTemplate let-post="post"> <app-post-view [Post]="post"></app-post-view> </ng-template> </app-widget-component> <br> <br> <app-widget-component Title=" ( )"> <ng-template appWidgetContentTemplate let-post="post"> <app-post-view [Post]="post" [ShowPostInfo]="ShowPostInfo"></app-post-view> </ng-template> </app-widget-component>
Portanto, temos um componente de widget que aceita e exibe qualquer conteúdo, enquanto o próprio componente de widget não precisa saber nada sobre o conteúdo. Simplesmente encaminha as opções de chave. Leia-os ou não é uma questão de conteúdo.

A versão completa do código pode ser vista
aqui .