Angular2: componente de renderizado sin su etiqueta envolvente

Resuelto Greg asked hace 8 años • 8 respuestas

Estoy luchando por encontrar una manera de hacer esto. En un componente principal, la plantilla describe a tabley su theadelemento, pero delega la representación tbodya 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 tretiqueta, 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 tbodysolo puede contener trelementos (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, ViewContainerRefpero, por lo que puedo ver, no parecen proporcionar una solución a esto.

Greg avatar Aug 02 '16 16:08 Greg
Aceptado

Puedes usar selectores de atributos.

@Component({
  selector: '[myTd]'
  ...
})

y luego usarlo como

<td myTd></td>
Günter Zöchbauer avatar Aug 02 '2016 09:08 Günter Zöchbauer

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);
}
G. Modebadze avatar Jul 04 '2019 12:07 G. Modebadze