Estou tentando construir um componente personalizado usando vários ng-content
no Angular 6, mas isso não está funcionando e não tenho ideia do porquê.
Este é o meu código de componente:
<div class="header-css-class">
<ng-content select="#header"></ng-content>
</div>
<div class="body-css-class">
<ng-content select="#body"></ng-content>
</div>
Estou tentando usar este componente em outro lugar e renderizar dois códigos HTML diferentes dentro body
e no cabeçalho select
de ng-content
, algo assim:
<div #header>This should be rendered in header selection of ng-content</div>
<div #body>This should be rendered in body selection of ng-content</div>
Mas o componente está sendo renderizado em branco.
Vocês sabem o que posso estar fazendo de errado ou qual é a melhor maneira de renderizar duas seções diferentes no mesmo componente?
Obrigado!
angular
angular6
angular-components
ng-content
Lucas santos
fonte
fonte
Respostas:
header
ebody
em oposição a referências de modelo(#header, #body)
.ng-content
comselect
atributo comoselect="[header]"
.app.comp.html
<app-child> <div header >This should be rendered in header selection of ng-content</div> <div body >This should be rendered in body selection of ng-content</div> </app-child>
child.comp.html
<div class="header-css-class"> <ng-content select="[header]"></ng-content> </div> <div class="body-css-class"> <ng-content select="[body]"></ng-content> </div>
DEMO
fonte
<div header>
por<ng-container header>
.<div header>
com<ng-container header>
trabalhos também.Para se adequar às especificações do Web Component . Mesmo que seja Angular. Trata-se de evitar atributos para seletores como diretivas angulares ou atributos reservados com outro uso. Portanto, usamos apenas o atributo "slot". Veremos
<ng-content select="[slot=foobar]">
como<slot name="foobar">
.Exemplo:
hello-world.component.html
<ng-content select="[slot=start]"></ng-content> <span>Hello World</span> <ng-content select="[slot=end]"></ng-content>
app.component.html
<app-hello-world> <span slot="start">This is a </span> <span slot="end"> example.</span> </app-hello-world>
Resultado
Exemplo Stackblitz
Você pode usar qualquer nome que quiser, como "banana" ou "peixe". Mas "início" e "fim" são uma boa convenção para colocar elementos antes e depois.
fonte
:host
e::ng-deep
em SCSS. Mas este é apenas um exemplo. Veja Stackblitz Talvez::slotted
/::content
também funcione. Mas não tenho certeza. A web oferecerá mais sobre este assunto. Geralmente, você deve estilizar apenas o próprio componente. E evite estilizar coisas fora (global). Caso contrário, você terá efeitos colaterais indesejados.<div class="end"><ng-content></ng-content></div>
Por exemplo, porque este elemento está acessível no componente. O ng-content é apenas um pseudo elemento que é substituído pelo elemento ancorado externo. Então você tem que usar o seletor ng-deep.alternativamente, você pode usar:
app.comp.html
<app-child> <div role="header">This should be rendered in header selection of ng-content</div> <div role="body">This should be rendered in body selection of ng-content</div> </app-child>
child.comp.html
<div class="header-css-class"> <ng-content select="div[role=header]"></ng-content> </div> <div class="body-css-class"> <ng-content select="div[role=body]"></ng-content> </div>
fonte
Complementando as demais respostas:
Você também pode fazer com tags (como
<ion-card>
,<ion-card-header>
, e<ion-card-content>
).app.comp.html
<app-child> <app-child-header>This should be rendered in header selection of ng-content</app-child-header> <app-child-content>This should be rendered in content selection of ng-content</app-child-content> </app-child>
child.comp.html
<div class="header-css-class"> <ng-content select="app-child-header"></ng-content> </div> <div class="content-css-class"> <ng-content select="app-child-content"></ng-content> </div>
Você receberá uma mensagem de aviso, mas funcionará. Você pode suprimir as mensagens de aviso ou usar marcas conhecidas como
header
oufooter
. No entanto, se você não gosta de nenhum desses métodos, escolha uma das outras soluções.fonte