206 votes

Angular2: restituer un composant sans sa balise wrapping

J'ai du mal à trouver un moyen pour ce faire. Dans un composant parent, le modèle décrit une table et son thead élément, mais les délégués du rendu de l' tbody à un autre composant, comme ceci:

<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>

Chaque myResult composant rend sa propre tr balise, essentiellement comme suit:

<tr>
  <td>{{ entry.name }}</td>
  <td>{{ entry.time }}</td>
</tr>

La raison pour laquelle je ne mets pas directement dans le composant parent (en évitant la nécessité d'une myResult composant) est que le myResult composant est en fait plus compliqué que ce qui est illustré ici, donc j'ai envie de mettre son comportement dans une composante distincte et fichier.

Le résultant DOM est de mauvaise qualité. Je crois que c'est parce qu'il est invalide, tbody ne peut contenir qu' tr éléments (voir MDN), mais mon généré (simplifié) DOM est :

<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>

Est-il possible de faire la même chose rendus, mais sans l'emballage <my-result> balise, et toujours à l'aide d'un composant à être seul responsable pour le rendu d'une ligne de tableau ?

J'ai regardé ng-content, DynamicComponentLoader, l' ViewContainerRef, mais ils ne semblent pas apporter une solution à ce aussi loin que je peux voir.

171voto

Günter Zöchbauer Points 21340

Vous pouvez utiliser des sélecteurs d'attributs

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

et ensuite l'utiliser comme

 <td myTd></td>
 

14voto

Shlomi Aharoni Points 144

Utilisez cette directive sur votre élément

 @Directive({
   selector: '[remove-wrapper]'
})
export class RemoveWrapperDirective {
   constructor(private el: ElementRef) {
       const parentElement = el.nativeElement.parentElement;
       const element = el.nativeElement;
       parentElement.removeChild(element);
       parentElement.parentNode.insertBefore(element, parentElement.nextSibling);
       parentElement.parentNode.removeChild(parentElement);
   }
}
 

Exemple d'utilisation:

 <div class="card" remove-wrapper>
   This is my card component
</div>
 

et dans le code HTML parent, vous appelez l'élément de carte comme d'habitude, par exemple:

 <div class="cards-container">
   <card></card>
</div>
 

La sortie sera:

 <div class="cards-container">
   <div class="card" remove-wrapper>
      This is my card component
   </div>
</div>
 

0voto

Neeraj Points 135

en dehors de la réponse sélectionnée ci-dessus, vous pouvez également utiliser ng-template ou ng-container

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X