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ą
ngStyle
ingClass
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 DOM
w przypadku elementu Angular - Korzystanie z
entryComponents
- Importowanie i używanie modułu
CreateCustomElement
z 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
.