Estou lutando para encontrar uma maneira de fazer isso. Em um componente pai, o modelo descreve um table
e seu thead
elemento, mas delega a renderização de tbody
para outro componente, como este:
<table>
<thead>
<tr>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody *ngFor="let entry of getEntries()">
<my-result [entry]="entry"></my-result>
</tbody>
</table>
Cada componente myResult renderiza sua própria tr
tag, basicamente assim:
<tr>
<td>{{ entry.name }}</td>
<td>{{ entry.time }}</td>
</tr>
O motivo pelo qual não estou colocando isso diretamente no componente pai (evitando a necessidade de um componente myResult) é que o componente myResult é, na verdade, mais complicado do que o mostrado aqui, portanto, quero colocar seu comportamento em um componente e arquivo separados.
O DOM resultante parece ruim. Acredito que seja porque ele é inválido, pois tbody
só pode conter tr
elementos (consulte MDN) , mas meu DOM gerado (simplificado) é:
<table>
<thead>
<tr>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<my-result>
<tr>
<td>Bob</td>
<td>128</td>
</tr>
</my-result>
</tbody>
<tbody>
<my-result>
<tr>
<td>Lisa</td>
<td>333</td>
</tr>
</my-result>
</tbody>
</table>
Existe alguma maneira de obtermos a mesma coisa renderizada, mas sem a <my-result>
marca de empacotamento , e ainda usando um componente para ser o único responsável por renderizar uma linha da tabela?
Eu olhei ng-content
, DynamicComponentLoader
, o ViewContainerRef
, mas eles não parecem fornecer uma solução para este, tanto quanto eu posso ver.
fonte
Respostas:
Você pode usar seletores de atributo
e então usá-lo como
fonte
[]
? Você adicionou o componentedeclarations: [...]
de um módulo? Se o componente está registrado em um módulo diferente, você adicionou este outro módulo aoimports: [...]
do módulo onde deseja usar o componente?setAttribute
não é meu código. Mas eu descobri, eu precisava usar a marca de nível superior real em meu modelo como a marca para meu componente em vez deng-container
usar o novo uso<ul smMenu class="nav navbar-nav" [submenus]="root?.Submenus" [title]="root?.Title"></ul>
<ul class="nav navbar-nav"> <li-navigation [navItems]="menuItems"></li-navigation> </ul>
Eu usei isto (depois de alterar a navegação para um seletor de atributo)<ul class="nav navbar-nav" li-navigation [navItems]="menuItems"></ul>
Você precisa de "ViewContainerRef" e dentro do componente my-result faça algo assim:
html:
ts:
fonte
@ViewChild('template', {static: true}) template;
my-result
precisa ser capaz de criar novosmy-result
irmãos. Então, imagine que você tem uma hierarquia demy-result
onde cada linha pode ter linhas "filhas". Nesse caso, usar um seletor de atributo não funcionaria, pois o primeiro seletor vai notbody
, mas o segundo não pode ir em um internotbody
nem em atr
.Use esta diretiva em seu elemento
Exemplo de uso:
e no HTML pai você chama o elemento cartão como de costume, por exemplo:
O resultado será:
fonte
Os seletores de atributos são a melhor maneira de resolver esse problema.
Então, no seu caso:
meus resultados ts
meus-resultados html
meu-resultado ts
meu-resultado html
Veja stackblitz de trabalho: https://stackblitz.com/edit/angular-xbbegx
fonte
você pode tentar usar o novo css
display: contents
aqui está minha barra de ferramentas scss:
e o html:
e em uso:
fonte
Outra opção hoje em dia é o
ContribNgHostModule
disponibilizado na@angular-contrib/common
embalagem .Depois de importar o módulo, você pode adicioná-lo
host: { ngNoHost: '' }
ao seu@Component
decorador e nenhum elemento de embalagem será renderizado.fonte