1. Wprowadzenie
Autor gościnny: Aayush Arora
Angular Elements to komponenty Angulara spakowane jako elementy niestandardowe. Są one obecnie obsługiwane przez Chrome, Operę i Safari, a w innych przeglądarkach są dostępne dzięki polyfillom. Te elementy mogą korzystać z całej infrastruktury Angulara ze wspólnym interfejsem Angulara i strategią wykrywania zmian. Po zarejestrowaniu można ich używać w przeglądarce.
W tym samouczku dowiesz się, jak utworzyć własny komponent Angulara do przesuwania obrazów, a następnie przekształcić go w element Angulara, aby mógł działać poza platformą Angular.
Co utworzysz
|
W tym ćwiczeniu w Codelabs utworzysz element suwaka obrazów za pomocą Angulara. Twój element wi:
|
Czego się nauczysz
- Jak utworzyć komponent niestandardowy w postaci suwaka obrazów
- Jak przekształcić komponent niestandardowy image-slider w element niestandardowy
- Jak spakować komponent, aby działał w przeglądarce
Czego potrzebujesz
- Mieć najnowszą wersję angular-cli.
- Przykładowy kod
- edytor tekstu,
- Podstawowa wiedza o komponentach Angular
Ten codelab dotyczy elementów Angulara. Nieistotne koncepcje i bloki kodu zostały pominięte. Można je po prostu skopiować i wkleić.
2. Przygotowania
Pobieranie kodu
Aby pobrać cały kod do tego laboratorium, kliknij ten link:
Rozpakuj pobrany plik ZIP. Spowoduje to rozpakowanie folderu głównego (angular-element-codelab-master), który zawiera
dwa foldery: (image-slider) i (image-slider-finished). Całą pracę związaną z kodowaniem będziemy wykonywać w katalogu o nazwie image-slider.
Realizacja projektu
Aby uruchomić projekt, musisz uruchomić polecenie ( ng-serve ) w katalogu głównym ( image-slider ).
Po uruchomieniu aplikacji zobaczysz:

3. Tworzenie komponentu niestandardowego Image-Slider
Jak utworzyć suwak obrazów?
W przypadku tego suwaka obrazów powiąż przyciski za pomocą wiązania kliknięcia Angular. Utworzymy tablicę obiektów zawierającą obrazy, tagi alt, linki itp. Umieścimy te obrazy jeden pod drugim w kontenerze i przetłumaczymy kontener po kliknięciu.
Utworzymy komponent suwaka obrazów, a następnie przekształcimy go w element Angulara.
- Kontener na obrazy i tytuły.
- tablica zawierająca dane;
- Szablon do powiązania danych
4. Implementowanie komponentu suwaka obrazów
Istnieje wiele sposobów na rozpoczęcie dowolnego projektu. W tym przypadku, aby jak najbardziej uprościć projekt i skoncentrować się na elementach Angular, udostępniliśmy podstawowy kod wraz z CSS.
Tworzenie tablicy i usługi danych
Pamiętaj, że tablica sliderArray będzie zawierać:
- Klucz img dla adresu URL obrazu w suwaku.
- Tag alt, który zawiera tekst alternatywny obrazu.
- Tekst opisujący obraz.
Plik data.json, który znajduje się już w katalogu src/assets, powinien wyglądać mniej więcej tak:
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'}
];
Musimy pobrać te dane w naszym komponencie za pomocą usługi. W pliku data.service.ts napiszemy metodę getData(), która będzie korzystać z modułu httpClient z @angular/common/http i pobierać dane z utworzonej powyżej tablicy.
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)
}
}
Pobieranie danych z usługi danych
Musimy zaimportować usługę w komponencie, a następnie zasubskrybować obiekt observable, aby pobrać obiekt z data.json.
W tym celu musimy wykonać 3 kroki:
- Inicjowanie tablicy komponentów
- Subskrybowanie obiektu Observable zwróconego przez funkcję
getData() - Utwórz interfejs Result, aby po zasubskrybowaniu obiektu Observable sprawdzić typ danych.
- Przypisz dane do tablicy komponentów.
Inicjowanie tablicy komponentów
Zadeklarujemy i zainicjujemy tablicę komponentów wewnątrz slider.component.ts, która jest tablicą obiektów:
Aby zadeklarować:
sliderArray: object[];
Aby zainicjować:
constructor(private data: DataService) {
this.sliderArray = [];
}
Następnie musimy zaimportować i zainicjować naszą usługę w konstruktorze.
constructor(private data: DataService) {}
Teraz możemy korzystać z naszej usługi i wywoływać jej metody.
Pobieranie danych z usługi danych
Aby pobrać dane z usługi, wywołamy metodę getData() i zasubskrybujemy zwracany przez nią obiekt observable. Utworzymy też interfejs Result,, aby sprawdzić, czy otrzymujemy prawidłowe dane.
Zrobimy to w metodzie ngOnInit:
this.data.getData().subscribe((result: Result)=>{
})
Przypisywanie danych do tablicy komponentów
Na koniec przypiszemy dane do tablicy komponentów:
this.data.getData().subscribe((result: Result)=>{
this.sliderArray = result.sliderArray;
})
Gdy dane znajdą się w tablicy komponentu, możemy powiązać szablon z tymi danymi.
W slider.component.html, mamy już szablon HTML. Kolejnym krokiem jest powiązanie tego szablonu z sliderArray.
5. Powiązanie danych z szablonem
Połączymy dane z szablonem za pomocą dyrektywy *ngFor, a następnie dodamy do szablonu przekształcenia, aby suwak działał.
Składa się ona z 3 kroków:
- Powiązywanie szablonu z elementem
sliderArray - Dodawanie powiązania zdarzenia dla przycisków suwaka
- Dodawanie przekształceń CSS za pomocą
ngStyleingClass
Powiązanie tablicy slideArray z komponentem
Mamy kontener zawierający img-container, a text-container i a slider..
Połączymy dane we wszystkich 3 kontenerach za pomocą dyrektywy *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>
Powiązanie zdarzenia z tablicą slideArray
Po powiązaniu danych powiążemy zdarzenie kliknięcia z każdym przyciskiem suwaka za pomocą funkcji click binding w Angularze. Utworzymy funkcję o nazwie selected(x), gdzie x to indeks tablicy.
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;
}
}
Ważne informacje:
- Wybrana funkcja zmniejsza wartość właściwości przekształcenia 50 razy w stosunku do indeksu przekazanego po kliknięciu funkcji
selected. - Ta logika tłumaczy kontener tekstu na 100%, 50%, -50% i -100%, co daje 4 różne stany.
Dodawanie przekształceń CSS za pomocą ngStyle i ngClass
Początkowo ustawiamy wszystkie obrazy na nieprzezroczyste (wartość 0). Gdy wybrany indeks jest równy indeksowi obrazu, dodajemy klasę selected za pomocą ngClass directive. Ta klasa selected dodaje do obrazu nieprzezroczystość równą 1, dzięki czemu obraz jest widoczny dla użytkownika.
<div class="img-container" *ngFor="let i of sliderArray; let select = index;"
[ngClass]="{'selected': select == selectedIndex}">
</div>
Następnie przetłumaczymy kontener tekstu zgodnie z wartością transform obliczoną za pomocą funkcji select().
<div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
</div>
Po wykonaniu wszystkich tych czynności możesz sprawdzić ostateczny kod, jak podano poniżej:
<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. Przekształcanie komponentu w element Angulara
Ta procedura obejmuje 5 kroków:
- Używanie
Shadow DOMw przypadku elementu Angular - Korzystanie z
entryComponents - Importowanie i używanie modułu
CreateCustomElementz usługi@angular/elements - Definiowanie
custom-element - Uruchomiono
ngDoBootstrap
Używanie modelu Shadow DOM w przypadku elementu Angular
Mamy już działający suwak obrazów, musimy tylko przekształcić go w Angular Element.
Zabawne jest to, że aby przekształcić DOM komponentu w Shadow DOM, wystarczy niewielka zmiana.
Musimy zaimportować moduł ViewEncapsulation i użyć metody ShadowDom.
@Component({
selector: 'app-slider',
templateUrl: './slider.component.html',
styleUrls: ['./slider.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
Korzystanie z entryComponents
Komponent Entry to komponent, który Angular wczytuje w sposób imperatywny. Komponent wejściowy określa się przez uruchomienie go w module NgModule.
Tutaj określimy nasz SliderComponent w tablicy entryComponents wewnątrz @NgModule
@NgModule({
declarations: [
SliderComponent
],
imports: [
BrowserModule,
HttpClientModule
]
})
Importowanie i używanie modułu createCustomElement
W tym przypadku musimy użyć modułu createCustomElement z @angular/elements.. Musisz użyć SliderComponent, jako parametru funkcji createCustomElement. Następnie musimy zarejestrować element slider w DOM.
import { createCustomElement } from '@angular/elements';
export class AppModule {
constructor(private injector: Injector) {
const slider = createCustomElement(SliderComponent, { injector });
}
}
Aby zarejestrować suwak jako element DOM, zdefiniujemy go za pomocą metody customElements.define.
customElements.define('motley-slider', slider);
Na koniec musimy zainicjować ten element niestandardowy za pomocą metody ngDoBootstrap(). Pełny kod będzie wyglądać tak:
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() {}
}
Pakowanie elementu Angular
Musimy zmodyfikować package.json za pomocą nowych poleceń. W tym celu zmodyfikujemy obiekt skryptu w pliku package.json.
Sprawdźmy zmodyfikowany obiekt skryptu:
"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"
}
Teraz możemy uruchomić polecenie ng build & ng package, a na koniec uruchomimy polecenie ng serve, aby udostępnić folder dist/ wygenerowany za pomocą polecenia build. Możemy też użyć gzip uzyskanego za pomocą polecenia ng package, wyodrębnić go i opublikować jako npm module.
