1. Einführung
Gastautor: Aayush Arora
Angular-Elemente sind Angular-Komponenten, die als benutzerdefinierte Elemente verpackt sind. Sie werden derzeit von Chrome, Opera und Safari unterstützt und sind in anderen Browsern über Polyfills verfügbar. Diese Elemente können die gesamte Angular-Infrastruktur mit der gemeinsamen Angular-Schnittstelle und der Strategie zur Änderungserkennung nutzen. Nach der Registrierung können diese Elemente im Browser verwendet werden.
In diesem Codelab erfahren Sie, wie Sie eine eigene Angular-Komponente für einen Bild-Slider erstellen und sie dann in ein Angular-Element umwandeln, damit sie außerhalb des Angular-Frameworks verwendet werden kann.
Überblick
In diesem Codelab erstellen Sie ein Bildschieberegler-Element mit Angular. Ihr Element:
|
Lerninhalte
- Benutzerdefinierte Komponente für einen Bild-Slider erstellen
- Benutzerdefinierte Komponente „Bild-Slider“ in ein benutzerdefiniertes Element umwandeln
- Komponente so verpacken, dass sie im Browser funktioniert
Voraussetzungen
- Eine aktuelle Version von angular-cli.
- Der Beispielcode
- Ein Texteditor
- Grundkenntnisse zu Angular-Komponenten
In diesem Codelab geht es um Angular-Elemente. Auf irrelevante Konzepte wird nicht genauer eingegangen und entsprechende Codeblöcke können Sie einfach kopieren und einfügen.
2. Einrichtung
Code herunterladen
Klicken Sie auf den folgenden Link, um den gesamten Code für dieses Codelab herunterzuladen:
Entpacken Sie die heruntergeladene ZIP-Datei. Dadurch wird ein Stammordner (angular-element-codelab-master)
entpackt, der Folgendes enthält:
zwei Ordner (image-slider)
und (image-slider-finished)
. Wir werden alle unsere Programmierarbeiten in einem Verzeichnis namens „image-slider“ durchführen.
Projekt durchführen
Um das Projekt auszuführen, müssen Sie den Befehl ( ng-serve) im Stammverzeichnis ( image-slider) ausführen.
Sobald die App gebootstrappt wurde, sehen Sie Folgendes:
3. Benutzerdefinierte Komponente für einen Bild-Slider erstellen
Wie erstelle ich einen Bild-Slider?
Binden Sie für diesen Bild-Slider Schaltflächen mit der Angular-Klickbindung. Wir erstellen ein Array mit Objekten, die Bilder, Alt-Tags, Links usw. enthalten. Diese Bilder werden in einem Container übereinander platziert und der Container wird per Klick übersetzt.
Wir erstellen eine Bild-Slider-Komponente und wandeln sie dann in ein Angular-Element um.
- Container für Bilder und Titel.
- Ein Array mit den Daten
- Vorlage zum Binden der Daten
4. Komponente „Bild-Slider“ implementieren
Es gibt mehrere Möglichkeiten, mit einem Projekt zu beginnen. In diesem Fall haben wir Ihnen grundlegenden Code zusammen mit dem CSS zur Verfügung gestellt, um unser Projekt so einfach wie möglich zu halten und uns auf Angular-Elemente zu konzentrieren.
Array und Datenservice erstellen
Das sliderArray enthält:
- Ein „img“-Schlüssel für die Bild-URL im Slider
- Ein ALT-Tag, um einen alternativen Text für das Bild anzugeben
- Ein Text, der das Bild beschreibt
Die data.json
-Datei, die sich bereits in Ihrem src/assets
-Verzeichnis befindet, sollte in etwa so aussehen.
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'}
];
Wir müssen diese Daten in unserer Komponente über einen Dienst abrufen. In der Datei data.service.ts
schreiben wir eine getData()
-Methode mit dem httpClient
-Modul aus @angular/common/http
, mit der die Daten aus dem oben erstellten Array abgerufen werden.
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)
}
}
Daten aus dem Datendienst abrufen
Wir müssen unseren Dienst in die Komponente importieren und dann das Observable abonnieren, um das Objekt aus data.json
abzurufen.
Dazu sind drei Schritte erforderlich:
- Komponentenarray initialisieren
- Observable abonnieren, das von der Funktion
getData()
zurückgegeben wird - Erstellen Sie eine Schnittstelle Result, um die Daten nach dem Abonnieren des Observables auf Typen zu prüfen.
- Weisen Sie die Daten dem Komponentenarray zu.
Komponenten-Array initialisieren
Wir deklarieren und initialisieren das Komponenten-Array in slider.component.ts
. Es handelt sich dabei um ein Array von Objekten:
So deklarieren Sie:
sliderArray: object[];
So initialisieren Sie:
constructor(private data: DataService) {
this.sliderArray = [];
}
Als Nächstes müssen wir unseren Dienst im Konstruktor importieren und initialisieren.
constructor(private data: DataService) {}
Jetzt können wir unseren Dienst verwenden und seine Methoden aufrufen.
Daten aus dem Data Service abrufen
Um die Daten aus dem Dienst abzurufen, rufen wir die Methode getData()
auf und abonnieren das Observable, das sie zurückgibt. Außerdem erstellen wir eine Schnittstelle Result,
, damit wir überprüfen können, ob wir die richtigen Daten erhalten.
Das machen wir in der Methode ngOnInit
:
this.data.getData().subscribe((result: Result)=>{
})
Daten dem Komponentenarray zuweisen
Am Ende weisen wir die Daten dem Komponenten-Array zu:
this.data.getData().subscribe((result: Result)=>{
this.sliderArray = result.sliderArray;
})
Sobald die Daten im Array unserer Komponente sind, können wir unser Template daran binden.
Im slider.component.html,
haben wir bereits eine HTML-Vorlage. Im nächsten Schritt binden wir diese Vorlage an das sliderArray
.
5. Daten an die Vorlage binden
Wir binden die Daten mit der Vorlage mithilfe der *ngFor
-Anweisung und fügen schließlich Transformationen in der Vorlage hinzu, damit der Slider funktioniert.
Dazu sind drei Schritte erforderlich:
sliderArray
an die Vorlage binden- Event-Binding für Slider-Schaltflächen hinzufügen
- CSS-Transformationen mit
ngStyle
undngClass
hinzufügen
slideArray an die Komponente binden
Wir haben einen Container mit einem img-container
, a
text-container
und a
slider.
.
Wir binden die Daten in allen drei Containern mit der *ngFor
-Anweisung.
<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 für slideArray
Sobald die Daten gebunden sind, binden wir das Klickereignis mit Angular click binding
an jede Schaltfläche. Wir erstellen eine Funktion namens selected(x)
, wobei x der Index des Arrays ist.
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;
}
}
Wichtige Hinweise:
- Die ausgewählte Funktion verringert den Wert der Transformations-Property um das Fünfzigfache des Index, der beim Klicken auf die
selected
-Funktion übergeben wird. - Diese Logik übersetzt den Textcontainer in 100%, 50%, -50 % und -100 %, was zu vier verschiedenen Status führt.
CSS-Transformationen mit ngStyle und ngClass hinzufügen
Zuerst legen wir für alle Bilder eine Deckkraft von null fest. Dann fügen wir mit ngClass directive
die Klasse selected
hinzu, wenn der ausgewählte Index mit dem Bildindex übereinstimmt. Durch diese selected
-Klasse wird dem Bild eine Deckkraft von 1 zugewiesen, sodass es für den Nutzer sichtbar ist.
<div class="img-container" *ngFor="let i of sliderArray; let select = index;"
[ngClass]="{'selected': select == selectedIndex}">
</div>
Anschließend wird der Textcontainer entsprechend dem transform
-Wert übersetzt, der mit der Funktion select()
berechnet wurde.
<div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
</div>
Nachdem Sie alle diese Schritte ausgeführt haben, können Sie den endgültigen Code wie unten angegeben abrufen:
<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. Komponente in ein Angular-Element umwandeln
Dieser Vorgang besteht aus fünf Schritten:
Shadow DOM
für Angular-Element verwendenentryComponents
verwendenCreateCustomElement
-Modul aus@angular/elements
importieren und verwendencustom-element
definierenngDoBootstrap
-Methode ausführen
Shadow DOM für Angular-Element verwenden
Jetzt, da unser Bild-Slider läuft, müssen wir ihn nur noch in ein Angular Element
umwandeln.
Das Schöne daran ist, dass nur eine geringfügige Änderung erforderlich ist, um das DOM der Komponente in ein Shadow DOM zu ändern.
Wir müssen das Modul ViewEncapsulation
importieren und die Methode ShadowDom
daraus verwenden.
@Component({
selector: 'app-slider',
templateUrl: './slider.component.html',
styleUrls: ['./slider.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
entryComponents verwenden
Der Eintrag „Component“ ist eine Komponente, die imperativ geladen wird. Sie geben eine Einstiegskomponente an, indem Sie sie in einem NgModule booten.
Hier geben wir unsere SliderComponent
im entryComponents
-Array in @NgModule
an.
@NgModule({
declarations: [
SliderComponent
],
imports: [
BrowserModule,
HttpClientModule
]
})
createCustomElement-Modul importieren und verwenden
Hier müssen wir das createCustomElement
-Modul aus @angular/elements.
verwenden. Sie müssen SliderComponent,
als Parameter für die createCustomElement
-Funktion verwenden. Danach müssen wir slider
im DOM registrieren.
import { createCustomElement } from '@angular/elements';
export class AppModule {
constructor(private injector: Injector) {
const slider = createCustomElement(SliderComponent, { injector });
}
}
Um den Schieberegler als DOM-Element zu registrieren, definieren wir ihn mit der Methode customElements.define
.
customElements.define('motley-slider', slider);
Schließlich müssen wir dieses benutzerdefinierte Element mit der Methode ngDoBootstrap()
initialisieren. Der vollständige Code sieht so aus:
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() {}
}
Angular-Element verpacken
Wir müssen package.json
mit unseren neuen Befehlen ändern. Dazu bearbeiten wir das Skriptobjekt in der Datei package.json
.
Sehen wir uns das geänderte Skriptobjekt an:
"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"
}
Jetzt können wir den Befehl ng build & ng package
ausführen und schließlich „ng serve“, um den mit dem Build-Befehl generierten Ordner „dist/“ bereitzustellen. Außerdem können wir die gzip
aus dem ng package
-Befehl extrahieren und als npm module
veröffentlichen.