Transclusion dans Angular 2 avec ng-content

Transclusion dans Angular 2 avec ng-content

Introduction

Désolé, j’ai une bien triste nouvelle à vous annoncer. La transclusion a été perdue lors de la réécriture d’Angular 2. Mais rassurez-vous le mot transclusion a disparu mais le concept persiste.

La transclusion dans AngularJS permet de prendre du contenu (comme du HTML ou du texte par exemple), et de l’injecter dans un template à un point spécifique du DOM.

C’est maintenant possible dans Angular à travers des navigateurs modernes. Cette “transclusion” porte un nouveau nom, celui de Content Projection

 

Angular Content Projection

Il est temps de passer à l’action, nous allons voir maintenant comment utiliser le Content Projection dans Angular 2

 

Web Components

Dans les web components, nous avons l’élément <content>qui est d’ailleurs déprécié depuis, il est utilisé comme un point d’entrée “Shadow DOM”. Angular utilise le Shadow DOM à travers ViewEncapsulation. Ne vous inquiétez pas je reviendrai sur ces concepts plus en détails lors d’un prochain article.

La balise <content> était utilisée dans les versions Alpha d’Angular, elle a été changée par <ng-content>.

 

Single-slot content Projection

Nous allons simplement utiliser l’élément <ng-content> dans notre composant et c’est tout :

// my-component.component.ts
import { Component } from '@angular/core';
 
@Component({
  selector: 'my-component',
  template: `
<div class="my-component"></div>
` }) export class MyComponent {}

Pour l’utilisation de l’élément, nous allons importé MyComponent. Puis nous ajoutons du contenu entre les balises <my-component>

// app.component.ts
import { Component } from '@angular/core';
 
@Component({
  selector: 'my-app',
  template: `
<div class="app">This is my transcluded content!</div>
` }) export class AppComponent {}

DOM Output:

<div class="app">
 
&nbsp;
<div class="my-component">This is my transcluded content!</div>
&nbsp;
 
</div>

 

Multi-slot content Projection

Le multi-slot content projection est aussi facile que le single-slot.

Nous allons voir ça tout de suite à l’aide d’un exemple :

// app.component.ts
@Component({
  selector: 'my-app',
  template: `
    <div class="app">
      <my-component>
        <my-component-title>
          This is the Component title!
        </my-component-title>
        <my-component-content>
          And here's some awesome content.
        </my-component-content>
      </my-component>
    </div>
  `
})

Ici, nous avons <my-component-title> et <my-component-content> qui sont utilisés comme des composants custom. Maintenant nous voulons injecter le contenu entre ces différentes balises à l’endroit approprié. Pour faire cela, nous allons utiliser la propriété select dans MyComponent.

// my-component.component.ts
@Component({
  selector: 'my-component',
  template: `
    <div class="my-component">
      <div>
        Title:
        <ng-content select="my-component-title"></ng-content>
      </div>
      <div>
        Content:
        <ng-content select="my-component-content"></ng-content>
      </div>
    </div>
  `
})

DOM output:

<div class="app">
  <my-component>
    <div class="my-component">
      <div>
        Title:
        <my-component-title>
          This is the Component title!
        </my-component-title>
      </div>
      <div>
        Content:
        <my-component-content>
          And here's some awesome content.
        </my-component-content>
      </div>
    </div>
  </my-component>
</div>

Bonus

J’ai découvert ce qui va suivre dernièrement, et je souhaite le partager avec vous pour vous remercier d’avoir lu l’article jusqu’au bout.

Nous ne sommes pas obligés d’utiliser l’approche que j’ai décris tout au long de l’article. Il est possible d’utiliser une autre manière de faire avec document.querySelector

// app.component.ts
@Component({
  selector: 'my-app',
  template: `
    <div class="app">
      <my-component>
        <div class="my-component-title">
          This is the Component title!
        </div>
        <div class="my-component-content">
          And here's some awesome content.
        </div>
      </my-component>
    </div>
  `
})

Et faire correspondre les changements dans MyComponent via la balise select :

// my-component.component.ts
template: `
  <div class="my-component">
    <div>
      Title:
      <ng-content select=".my-component-title"></ng-content>
    </div>
    <div>
      Content:
      <ng-content select=".my-component-content"></ng-content>
    </div>
  </div>
`

 

Partagez, si vous aimez

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *