Google is committed to advancing racial equity for Black communities. See how.

Créer un élément de curseur d'image à l'aide d'Angular

Auteur invité : Aayush Arora

Les éléments Angular sont des composants Angular empaquetés en tant qu'éléments personnalisés. Ils sont actuellement compatibles avec Chrome, Opera et Safari et sont disponibles dans d'autres navigateurs via des polyfills. Ces éléments peuvent exploiter l'ensemble de l'infrastructure Angular à l'aide de la stratégie de détection des changements et de l'interface commune d'Angular. Une fois enregistrés, ils sont utilisables dans le navigateur.

Cet atelier de programmation vous explique comment créer un composant Angular de curseur d'image et comment le transformer en élément Angular afin qu'il puisse être utilisé en dehors du framework Angular.

Objectifs de cet atelier

Dans cet atelier de programmation, vous allez créer un élément de curseur d'image à l'aide d'Angular. Votre élément sera capable de :

  • fonctionner comme un élément HTML dans le navigateur ;
  • se connecter à tout framework capable de communiquer avec le DOM.

Points abordés

  • Créer un composant personnalisé de curseur d'image
  • Convertir le composant personnalisé de curseur d'image en élément personnalisé
  • Empaqueter le composant de sorte qu'il fonctionne dans le navigateur

Prérequis

Cet atelier de programmation traite principalement des éléments Angular. Les concepts et les blocs de codes non pertinents ne sont pas abordés, et vous sont fournis afin que vous puissiez simplement les copier et les coller.

Télécharger le code

Cliquez sur le lien ci-dessous pour télécharger l'ensemble du code de cet atelier de programmation :

Télécharger le code source

Décompressez le fichier ZIP téléchargé.Cela a pour effet de décompresser un dossier racine, (angular-element-codelab-master), qui contient

deux dossiers : (image-slider) et (image-slider-finished). Tout le travail de codage sera effectué dans le répertoire "image-slider".

Exécuter le projet

Pour exécuter le projet, vous devez exécuter la commande (ng-serve) à partir du répertoire racine (image-slider).

Une fois l'application amorcée, elle devrait se présenter comme suit :

19ffd082e2f024a5.png

Comment créer un curseur d'image ?

Pour ce curseur d'image, vous devez lier des boutons à l'aide d'une liaison de clic Angular. Il vous faut créer un tableau d'objets contenant des images (ainsi que des balises ALT, des liens, etc.), puis les placer les unes sous les autres dans un conteneur et appliquer une translation du conteneur lors d'un clic.

Une fois que vous avez créé un composant de curseur d'image, vous allez le convertir en élément Angular.

  • Conteneur pour les images et les titres
  • Tableau contenant les données
  • Modèle permettant de lier les données

Comme dans tout projet, il existe plusieurs façons de procéder. Ici, nous vous fournissons le code de base et le code CSS pour simplifier le processus et nous limiter à aborder les éléments Angular.

Créer un tableau et un service de données

Le tableau sliderArray devra contenir les éléments suivants :

  • Une clé img pour l'URL de l'image dans le curseur
  • Une balise ALT qui fournit le texte alternatif de l'image
  • Un texte qui fournit la description de l'image

Le fichier data.json qui se trouve déjà dans votre répertoire src/assets doit se présenter comme suit :

sliderArray = [
 {img: 'http://bloquo.cc/img/works/1.jpg', alt: '', text: '365 Days Of weddings a year'},
 {img: 'http://bloquo.cc/img/works/2.jpg', alt: '',  text: '365 Days Of weddings a year'},
 {img: 'http://bloquo.cc/img/works/3.jpg', alt: '', text: '365 Days Of weddings a year'},
 {img: 'http://bloquo.cc/img/works/4.jpg', alt: '',  text: '365 Days Of weddings a year'},
 {img: 'http://bloquo.cc/img/works/5.jpg', alt: '', text: '365 Days Of weddings a year'}
];

Vous devez utiliser un service pour récupérer ces données dans votre composant. Dans le fichier data.service.ts, il vous faut écrire une méthode getData() en utilisant le module httpClient de @angular/common/http, qui permet d'extraire les données du tableau que vous venez de créer.


import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'

const URL = '../assets/data.json';

@Injectable({
 providedIn: 'root'
})
export class DataService {

 constructor(private http: HttpClient) {}

 getData() {
   return this.http.get(URL)
 }
}

Récupérer les données du service de données

Vous devez importer le service fourni dans le composant, puis vous abonner à l'observable pour obtenir l'objet à partir de data.json.

Voici les trois étapes à suivre :

  • Initialiser un tableau de composants
  • Vous abonner à l'observable renvoyé par la fonction getData()
  • Créer une interface Result pour valider le type des données après avoir effectué cet abonnement
  • Attribuer les données au tableau de composants

Initialiser le tableau de composants

Déclarez et initialisez le tableau de composants dans slider.component.ts, qui est un tableau d'objets :

Déclaration :

sliderArray: object[];

Initialisation :

constructor(private data: DataService) {
 this.sliderArray = [];
}

Ensuite, importez et initialisez le service fourni dans le constructeur :

constructor(private data: DataService) {}

Vous pouvez désormais utiliser le service et appeler les méthodes de service.

Obtenir des données à partir du service de données

Pour obtenir les données à partir du service, vous devez appeler la méthode getData() et vous abonner à l'observable renvoyé. Il vous faut également créer une interface Result, pour vérifier que les données obtenues sont correctes.

C'est ce que vous allez définir dans la méthode ngOnInit :

this.data.getData().subscribe((result: Result)=>{
})

Attribuer les données au tableau de composants

Maintenant, attribuez les données au tableau de composants :

this.data.getData().subscribe((result: Result)=>{
  this.sliderArray = result.sliderArray;
})

Une fois que les données sont importés dans le tableau de composants, vous pouvez lier votre modèle à celles-ci.

Le fichier slider.component.html, fournit déjà un modèle HTML. La prochaine étape consiste à lier ce modèle à sliderArray.

Vous devez lier les données au modèle à l'aide de la directive *ngFor et, pour terminer, y ajouter des transformations pour que le curseur fonctionne.

Cela se résume à trois étapes :

  • Lier sliderArray au modèle
  • Ajouter une liaison d'événements pour les boutons du curseur
  • Ajouter des transformations CSS à l'aide de ngStyle et ngClass

Lier slideArray au composant

Vous disposez d'un conteneur avec img-container, a text-container et a slider..

Vous allez maintenant lier les données de ces trois sous-conteneurs à l'aide de la directive *ngFor.

<div class="container">
 <div class="img-container" *ngFor="let i of sliderArray; let select = index;">
   <img src="{{i.img}}" alt="{{i.alt}}" >
 </div>

 <div>
   <div class="text-container">
     <div class="page-text" *ngFor="let i of sliderArray;let select = index;">
       <h3>{{i.text}}</h3>
     </div>
   </div>
 </div>

</div>

<div class="slider">
 <div class="slide-button-parent-container" *ngFor="let i of sliderArray; let x =index">
    <div class="select-box">
     <div class="slide-button">
     </div>
    </div>
 </div>
</div>

Ajouter une liaison d'événements à slideArray

Une fois les données liées, vous devez lier l'événement de clic à chaque bouton à l'aide de la fonction click binding d'Angular. Il vous faut créer une fonction appelée selected(x), où x correspond à l'index du tableau.

selected(x) {
 this.downSelected(x);
 this.selectedIndex = x;
}

downSelected(i) {
  this.transform =  100 - (i) * 50;
  this.selectedIndex = this.selectedIndex + 1;
  if(this.selectedIndex > 4) {
    this.selectedIndex = 0;
  }
}

Points à retenir :

  • La fonction "downSelected" diminue de 50 fois la valeur de la propriété de transformation de l'index qui est transmise lors d'un clic pour la fonction selected.
  • Cette logique applique une translation de 100 %, 50 %, -50 % et -100 % pour le conteneur de texte, ce qui donne quatre états différents.

Ajouter des transformations CSS à l'aide de ngStyle et ngClass

Dans un premier temps, vous définissez l'opacité des images à zéro et ajoutez une classe selected à l'aide de la directive ngClass directive lorsque l'index sélectionné est égal à l'index de l'image. La classe selected ajoute une opacité de 1, ce qui rend l'image visible à l'utilisateur.

<div class="img-container"  *ngFor="let i of sliderArray; let select = index;"
      [ngClass]="{'selected': select == selectedIndex}">
</div>

Ensuite, vous appliquez une translation du conteneur de texte en fonction de la valeur transform calculée à l'aide de la fonction select().

<div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
</div>

Une fois que vous avez effectué ces étapes, le code final devrait se présenter comme suit :

<div class="container">
 <div class="img-container"  *ngFor="let i of sliderArray; let select = index;"
      [ngClass]="{'selected': select == selectedIndex}">
   <img src="{{i.img}}" alt="{{i.alt}}" >
 </div>

 <!--</div>-->
 <div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
   <div class="text-container">
     <div class="page-text" *ngFor="let i of sliderArray;let select = index;" [ngClass]="{'selected': select == selectedIndex}">
       <h3>{{i.text}}</h3>
     </div>
   </div>
 </div>

</div>

<div class="slider">
 <div class="slide-button-parent-container"  *ngFor="let i of sliderArray; let x =index" (click)="selected(x)" >
    <div class="select-box">
     <div   class="slide-button" [ngClass]="{'slide-button-select': x == selectedIndex}" >
     </div>
    </div>
 </div>
</div>

Cette procédure comprend cinq étapes :

  • Utiliser Shadow DOM pour l'élément Angular
  • Utiliser entryComponents
  • Importer et utiliser le module CreateCustomElement à partir de @angular/elements
  • Définir custom-element
  • Exécuter la méthode ngDoBootstrap

Utiliser Shadow DOM pour un élément Angular

Vous disposez maintenant d'un curseur d'image fonctionnel. Il ne vous reste plus qu'à le convertir en élément Angular Element.

En fait, il vous suffit de modifier légèrement le DOM du composant pour le convertir en Shadow DOM.

Pour ce faire, vous devez importer le module ViewEncapsulation et utiliser la méthode ShadowDom à partir de celui-ci.

@Component({
 selector: 'app-slider',
 templateUrl: './slider.component.html',
 styleUrls: ['./slider.component.css'],
 encapsulation: ViewEncapsulation.ShadowDom
})

Utiliser entryComponents

Le composant d'entrée (entryComponents) est un composant qui se charge de manière impérative. Pour spécifier un composant d'entrée, vous devez l'amorcer dans un NgModule.

Spécifiez le SliderComponent dans le tableau entryComponents dans @NgModule

@NgModule({
 declarations: [
   SliderComponent
 ],
 imports: [
   BrowserModule,
   HttpClientModule
 ],
 entryComponents: [SliderComponent],
})

Importer et utiliser le module createCustomElement

Maintenant, il s'agit d'utiliser le module createCustomElement à partir de @angular/elements.. Vous devez utiliser le SliderComponent, comme paramètre de la fonction createCustomElement. Il vous faut ensuite enregistrer le slider dans le DOM.

import { createCustomElement } from '@angular/elements';

export class AppModule {
 constructor(private injector: Injector) {
   const slider = createCustomElement(SliderComponent, { injector });
    }
}

Pour enregistrer le curseur en tant qu'élément DOM, vous devez le définir à l'aide de la méthode customElements.define :

customElements.define('motley-slider', slider);

Enfin, vous amorcez cet élément personnalisé à l'aide de la méthode ngDoBootstrap(). Le code complet se présente comme suit :

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { SliderComponent } from './slider/slider.component';
import { HttpClientModule} from "@angular/common/http";

@NgModule({
 declarations: [
   SliderComponent
 ],
 imports: [
   BrowserModule,
   HttpClientModule
 ],
 entryComponents: [SliderComponent],
})
export class AppModule {
 constructor(private injector: Injector) {
   const slider = createCustomElement(SliderComponent, { injector });
   customElements.define('motley-slider', slider);
 }

 ngDoBootstrap() {}

}

Empaqueter l'élément Angular

Vous devez modifier package.json pour y indiquer vos nouvelles commandes, autrement dit, modifier l'objet de script dans le fichier package.json.

Voici comment se présente l'objet de script modifié :

"scripts": {
 "ng": "ng",
 "start": "ng serve",
 "build": "ng build --prod --output-hashing=none",
 "package": "cat dist/my-app/{runtime,polyfills,scripts,main}.js | gzip > elements.js.gz",
 "serve": "http-server",
 "test": "ng test",
 "lint": "ng lint",
 "e2e": "ng e2e"
}

Vous pouvez maintenant exécuter la commande ng build & ng package, puis "ng serve" pour diffuser le dossier "dist/" généré à l'aide de la commande de création. Vous pouvez également utiliser le gzip obtenu à partir de la commande ng package, l'extraire et le publier en tant que npm module.