Angular2: componente de renderizado sin su etiqueta envolvente
Estoy luchando por encontrar una manera de hacer esto. En un componente principal, la plantilla describe a table
y su thead
elemento, pero delega la representación tbody
a otro componente, así:
<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 representa su propia tr
etiqueta, básicamente así:
<tr>
<td>{{ entry.name }}</td>
<td>{{ entry.time }}</td>
</tr>
La razón por la que no estoy poniendo esto directamente en el componente principal (evitando la necesidad de un componente myResult) es que el componente myResult es en realidad más complicado de lo que se muestra aquí, por lo que quiero poner su comportamiento en un componente y archivo separados.
El DOM resultante se ve mal. Creo que esto se debe a que no es válido, ya que tbody
solo puede contener tr
elementos (ver MDN) , pero mi DOM generado (simplificado) es:
<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>
¿Hay alguna manera de que podamos renderizar lo mismo usando un componente secundario para encapsular la representación de la fila de la tabla sin el ajuste?<my-result>
etiqueta envolvente?
He mirado ng-content
, DynamicComponentLoader
, ViewContainerRef
pero, por lo que puedo ver, no parecen proporcionar una solución a esto.
Puedes usar selectores de atributos.
@Component({
selector: '[myTd]'
...
})
y luego usarlo como
<td myTd></td>
Necesitas "ViewContainerRef" y dentro del componente my-result haz algo como esto:
.html
:
<ng-template #template>
<tr>
<td>Lisa</td>
<td>333</td>
</tr>
</ng-template>
.ts
:
@ViewChild('template', { static: true }) template;
constructor(
private viewContainerRef: ViewContainerRef
) { }
ngOnInit() {
this.viewContainerRef.createEmbeddedView(this.template);
}