Creare un elemento slider di immagini utilizzando Angular

1. Introduzione

Di Aayush Arora, autore ospite

Gli elementi Angular sono componenti Angular confezionati come elementi personalizzati. Al momento sono supportate da Chrome, Opera e Safari e sono disponibili in altri browser tramite polyfill. Questi elementi possono utilizzare l'intera infrastruttura Angular con l'interfaccia Angular comune e la strategia di rilevamento delle modifiche. Una volta registrati, questi elementi possono essere utilizzati all'interno del browser.

Questo codelab ti guiderà nella creazione del tuo componente Angular per lo slider di immagini e ti aiuterà a trasformarlo in un elemento Angular in modo che possa funzionare al di fuori del framework Angular.

Cosa creerai

In questo codelab, creerai un elemento di scorrimento delle immagini utilizzando Angular. Il tuo elemento wi:

  • funzionano come un elemento HTML nel browser
  • Può essere collegato a qualsiasi framework che interagisce con il DOM.

Cosa imparerai a fare

  • Come creare un componente personalizzato per lo slider di immagini
  • Come trasformare il componente personalizzato del cursore delle immagini in un elemento personalizzato
  • Come creare il pacchetto del componente in modo che funzioni all'interno del browser

Che cosa ti serve

Questo codelab è incentrato su Angular Elements. Concetti e blocchi di codice non pertinenti sono trattati solo superficialmente e sono forniti solo per operazioni di copia e incolla.

2. Preparazione

Scarica il codice

Fai clic sul seguente link per scaricare tutto il codice per questo codelab:

Decomprimi il file ZIP scaricato. Verrà estratta una cartella principale (angular-element-codelab-master), che contiene

due cartelle (image-slider) e (image-slider-finished). Eseguiremo tutto il lavoro di codifica in una directory denominata image-slider.

Esecuzione del progetto

Per eseguire il progetto, devi eseguire il comando ( ng-serve) dalla directory principale ( image-slider).

Una volta eseguito il bootstrap dell'app, potrai visualizzare questo messaggio:

19ffd082e2f024a5.png

3. Creare un componente personalizzato per lo slider di immagini?

Come creare un cursore di immagini?

Per questo cursore delle immagini, associa i pulsanti utilizzando l'associazione di clic angolare. Creeremo un array di oggetti contenenti immagini, tag alt, link e così via. Posizioneremo queste immagini una sotto l'altra in un contenitore e tradurremo il contenitore con un clic.

Creeremo un componente cursore di immagini e poi lo trasformeremo in un elemento Angular.

  • Contenitore per immagini e titoli.
  • Un array contenente i dati
  • Modello per associare i dati

4. Implementa il componente image-slider

Esistono diversi modi per iniziare un progetto. In questo caso, per mantenere il progetto il più semplice possibile e concentrarci su Angular Elements, ti abbiamo fornito il codice di base insieme al CSS.

Creare un array e un servizio dati

Ricorda che sliderArray conterrà:

  • Una chiave img per l'URL dell'immagine nel cursore
  • Un tag alt per fornire il testo alternativo per l'immagine
  • Un testo per fornire la descrizione dell'immagine

Il file data.json già presente nella directory src/assets dovrebbe avere un aspetto simile al seguente.

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'}
];

Dobbiamo recuperare questi dati nel nostro componente utilizzando un servizio. Nel file data.service.ts, scriveremo un metodo getData() utilizzando il modulo httpClient di @angular/common/http, che recupererà i dati dall'array creato in precedenza.

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

Recupero dei dati dal servizio di dati

Dobbiamo importare il nostro servizio all'interno del componente, quindi possiamo abbonarci all'observable per ottenere l'oggetto da data.json

Per farlo, dobbiamo seguire tre passaggi:

  • Inizializzazione di un array di componenti
  • Sottoscrizione all'observable restituito dalla funzione getData()
  • Crea un'interfaccia Result per il controllo del tipo di dati dopo la sottoscrizione all'observable.
  • Assegna i dati all'array di componenti.

Inizializzazione dell'array di componenti

Dichiariamo e inizializziamo l'array di componenti all'interno di slider.component.ts, che è un array di oggetti:

Per dichiarare:

sliderArray: object[];

Per inizializzare:

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

Successivamente, dobbiamo importare e inizializzare il nostro servizio all'interno del costruttore

constructor(private data: DataService) {}

Ora siamo pronti a utilizzare il nostro servizio e a chiamare i metodi del servizio.

Recupero dei dati dal servizio di dati

Per estrarre i dati dal servizio, chiameremo il metodo getData() e ci iscriveremo all'observable che restituirà. Creeremo anche un'interfaccia Result, per poter verificare il tipo di dati che riceviamo.

Lo faremo all'interno del metodo ngOnInit:

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

Assegnare dati all'array di componenti

Alla fine, assegneremo i dati all'array di componenti:

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

Una volta che i dati si trovano all'interno dell'array del componente, possiamo associare il modello a questi dati.

In slider.component.html, abbiamo già un modello HTML. Il passaggio successivo consiste nel collegare questo modello a sliderArray.

5. Associazione dei dati al modello

Collegheremo i dati al modello utilizzando la direttiva *ngFor e infine aggiungeremo le trasformazioni nel modello per far funzionare il cursore.

che prevede tre passaggi:

  • Associazione di sliderArray al modello
  • Aggiunta del binding degli eventi per i pulsanti del cursore
  • Aggiunta di trasformazioni CSS utilizzando ngStyle e ngClass

Associazione di slideArray al componente

Abbiamo un contenitore con img-container, a text-container e a slider.

Collegheremo i dati in tutti e tre i contenitori utilizzando la direttiva *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>

Event Binding to slideArray

Una volta associati i dati, collegheremo l'evento di clic a ogni pulsante a scorrimento utilizzando Angular click binding. Creeremo una funzione denominata selected(x), dove x è l'indice dell'array.

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

Punti da ricordare:

  • La funzione di selezione riduce il valore della proprietà di trasformazione di cinquanta volte l'indice passato al clic della funzione selected.
  • Questa logica traduce il contenitore di testo al 100%, 50%, -50%, -100%, ottenendo quattro stati diversi.

Aggiungere trasformazioni CSS utilizzando ngStyle e ngClass

Inizialmente impostiamo tutte le immagini con un'opacità pari a zero, aggiungiamo una classe selected utilizzando ngClass directive quando l'indice selezionato diventa uguale all'indice dell'immagine. Questa classe selected aggiunge un'opacità di uno all'immagine, rendendola visibile all'utente.

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

Dopodiché, tradurremo il contenitore di testo in base al valore transform calcolato utilizzando la funzione select().

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

Dopo aver eseguito tutti questi passaggi, puoi trovare il codice finale come indicato di seguito:

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

6. Trasformare il componente nell'elemento Angular

Questa procedura è composta da cinque passaggi:

  • Utilizzo di Shadow DOM per l'elemento angolare
  • Utilizzo di entryComponents
  • Importazione e utilizzo del modulo CreateCustomElement da @angular/elements
  • Definizione del nostro custom-element
  • Metodo di esecuzione ngDoBootstrap

Utilizzo di Shadow DOM per l'elemento Angular

Ora che lo slider delle immagini è in esecuzione, dobbiamo solo trasformarlo in un Angular Element.

La parte divertente è che c'è solo una piccola modifica per rendere il componente DOM, un DOM ombra.

Dobbiamo importare il modulo ViewEncapsulation e utilizzare il metodo ShadowDom.

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

Utilizzare entryComponents

La voce Component è un componente che Angular carica in modo imperativo. Specifichi un componente di voce avviandolo in un NgModule.

Qui specificheremo il nostro SliderComponent nell'array entryComponents all'interno di @NgModule

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

Importazione e utilizzo del modulo createCustomElement

Qui dobbiamo utilizzare il modulo createCustomElement di @angular/elements.. Devi utilizzare SliderComponent, come parametro della funzione createCustomElement. Dopodiché, dobbiamo registrare slider nel DOM.

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

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

Per registrare lo slider come elemento DOM, lo definiremo utilizzando il metodo customElements.define.

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

Infine, dobbiamo eseguire il bootstrap di questo elemento personalizzato utilizzando il metodo ngDoBootstrap(). Il codice completo sarà simile al seguente:

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
 ]
})
export class AppModule {
 constructor(private injector: Injector) {
   const slider = createCustomElement(SliderComponent, { injector });
   customElements.define('motley-slider', slider);
 }

 ngDoBootstrap() {}

}

Creazione del pacchetto dell'elemento Angular

Dobbiamo modificare package.json con i nostri nuovi comandi, quindi modificheremo l'oggetto script all'interno del file package.json.

Controlliamo l'oggetto script modificato:

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

Ora possiamo eseguire il comando ng build & ng package e infine eseguire ng serve per pubblicare la cartella dist/ generata utilizzando il comando build. Inoltre, possiamo utilizzare gzip ottenuto dal comando ng package, estrarlo e pubblicarlo come npm module.