О практической работе
1. Введение
Приглашенный автор Аюш Арора
Angular Elements — это компоненты Angular, упакованные как пользовательские элементы. В настоящее время они поддерживаются Chrome, Opera и Safari и доступны в других браузерах через полифиллы. Эти элементы могут использовать всю инфраструктуру Angular с общим интерфейсом Angular и стратегией обнаружения изменений. После регистрации эти элементы можно использовать в браузере.
Эта лабораторная работа проведет вас через создание вашего собственного компонента angular слайдера изображений, а затем поможет вам преобразовать его в элемент angular, чтобы он мог работать вне Angular Framework.
Что вы будете строить
В этой кодовой лаборатории вы собираетесь создать элемент слайдера изображения, используя angular. Ваш элемент с:
|
Что вы узнаете
- Как сделать пользовательский компонент слайдера изображений
- Как преобразовать пользовательский компонент слайдера изображения в пользовательский элемент
- Как упаковать компонент, чтобы он работал внутри браузера
Что вам понадобится
- Последняя версия angular-cli .
- Пример кода
- Текстовый редактор
- Базовые знания компонентов Angular.
Эта лаборатория кода ориентирована на Angular Elements. Нерелевантные концепции и блоки кода замалчиваются и предоставляются для простого копирования и вставки.
2. Подготовка
Скачать код
Щелкните следующую ссылку, чтобы загрузить весь код для этой лаборатории кода:
Распакуйте загруженный zip-файл. Это распакует корневую папку (angular-element-codelab-master)
, содержащую
две папки (image-slider)
и (image-slider-finished)
. Мы будем выполнять всю нашу работу по кодированию в каталоге с именем image-slider.
Запуск проекта
Для запуска проекта нужно запустить команду (ng-serve) из корневого каталога (image-slider).
Как только приложение загрузится, вы сможете увидеть это:
3. Создание пользовательского компонента Image-Slider?
Как создать слайдер изображений?
Для этого слайдера изображения привяжите кнопки, используя привязку углового клика. Мы создадим массив объектов, содержащих изображения, alt-теги, ссылки и т. д. Мы разместим эти изображения одно под другим в контейнере и будем транслировать контейнер по клику.
Мы собираемся создать компонент слайдера изображений, а затем преобразовать его в угловой элемент.
- Контейнер для изображений и заголовков.
- Массив, содержащий данные
- Шаблон для привязки данных
4. Реализовать компонент слайдера изображений
Есть несколько способов начать работу с любым проектом, в этом случае, чтобы сделать наш проект максимально простым и сосредоточиться на Angular Elements, мы предоставили вам базовый код вместе с css.
Создание массива и службы данных
Помните, что sliderArray будет содержать:
- Ключ img для URL-адреса изображения в слайдере.
- Тег alt для предоставления alt для изображения
- Текст для описания изображения
Файл data.json
, который уже находится в вашем каталоге src/assets
, должен выглядеть примерно так.
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'}
];
Нам нужно получить эти данные в нашем компоненте с помощью службы. В файле data.service.ts
мы напишем метод httpClient
getData()
, используя модуль httpClient из @angular/common/http
, который будет извлекать данные из массива, который мы создали выше.
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)
}
}
Получение данных из службы данных
Нам нужно импортировать наш сервис внутри компонента, а затем мы можем подписаться на наблюдаемое, чтобы получить объект из data.json
Для этого нам нужно выполнить три шага:
- Инициализация массива компонентов
- Подписка на Observable, возвращаемый функцией
getData()
- Создайте интерфейс Result для проверки типов данных после подписки на наблюдаемое.
- Назначьте данные массиву компонентов.
Инициализация массива компонентов
Мы объявим и инициализируем массив компонентов внутри slider.component.ts
, который представляет собой массив объектов:
Объявить:
sliderArray: object[];
Для инициализации:
constructor(private data: DataService) {
this.sliderArray = [];
}
Далее нам нужно импортировать и инициализировать наш сервис внутри конструктора
constructor(private data: DataService) {}
Теперь мы готовы использовать наш сервис и вызывать методы нашего сервиса.
Получение данных из службы данных
Чтобы получить данные из службы, мы вызовем метод getData()
и подпишемся на наблюдаемое, которое он вернет. Мы также создадим интерфейс Result,
чтобы мы могли ввести проверку того, что мы получаем правильные данные.
Мы сделаем это внутри метода ngOnInit
:
this.data.getData().subscribe((result: Result)=>{
})
Назначение данных массиву компонентов
В конце мы присвоим данные массиву компонентов:
this.data.getData().subscribe((result: Result)=>{
this.sliderArray = result.sliderArray;
})
Как только мы получим данные внутри массива нашего компонента, мы сможем связать наш шаблон с этими данными.
В slider.component.html,
у нас уже есть HTML-шаблон. Наш следующий шаг — привязать этот шаблон к sliderArray
.
5. Связывание данных с шаблоном
Мы свяжем данные с шаблоном с помощью директивы *ngFor
и, наконец, добавим преобразования в шаблон, чтобы слайдер заработал.
Это включает три шага:
- Привязка
sliderArray
к шаблону - Добавление привязки событий для кнопок ползунка
- Добавление CSS-преобразований с использованием
ngStyle
иngClass
Связывание массива слайдов с компонентом
У нас есть контейнер, содержащий img-container
a
text-container
a
slider.
Мы свяжем данные во всех трех контейнерах с помощью директивы *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>
Привязка события к массиву слайдов
Как только данные будут привязаны, мы привяжем событие щелчка к каждой ползунковой кнопке, используя угловую click binding
. Мы создадим функцию с именем selected(x)
, где x — индекс массива.
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;
}
}
Здесь следует помнить:
- Выбранная функция уменьшает значение свойства преобразования в пятьдесят раз по сравнению с индексом, переданным при щелчке
selected
функции. - Эта логика преобразует текстовый контейнер в 100%, 50%, -50%, -100%, что приводит к четырем различным состояниям.
Добавление преобразований CSS с помощью ngStyle и ngClass
Изначально мы устанавливаем все изображения с нулевой непрозрачностью, мы добавляем класс, selected
с помощью ngClass directive
когда выбранный индекс становится равным индексу изображения. Этот selected
класс добавляет к изображению непрозрачность, равную единице, что делает изображение видимым для пользователя.
<div class="img-container" *ngFor="let i of sliderArray; let select = index;"
[ngClass]="{'selected': select == selectedIndex}">
</div>
После этого мы переведем текстовый контейнер в соответствии со значением transform
, вычисленным с помощью функции select()
.
<div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
</div>
После того, как вы выполнили все эти шаги, вы можете узнать окончательный код, как показано ниже:
<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. Преобразование компонента в угловой элемент
Эта процедура состоит из пяти шагов:
- Использование
Shadow DOM
для углового элемента - Использование
entryComponents
- Импорт и использование модуля
CreateCustomElement
из@angular/elements
- Определение нашего
custom-element
- Запуск метода
ngDoBootstrap
Использование Shadow DOM для углового элемента
Теперь у нас есть слайдер изображений, нам просто нужно сделать его Angular Element
.
Самое интересное, что есть лишь незначительное изменение для создания DOM компонента, теневого DOM.
Нам нужно импортировать модуль ViewEncapsulation
и использовать из него метод ShadowDom
.
@Component({
selector: 'app-slider',
templateUrl: './slider.component.html',
styleUrls: ['./slider.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
Использование entryComponents
Компонент входа — это компонент, который принудительно загружается под углом. Вы указываете компонент записи, загружая его в NgModule.
Здесь мы укажем наш SliderComponent
в массиве entryComponents
внутри @NgModule
@NgModule({
declarations: [
SliderComponent
],
imports: [
BrowserModule,
HttpClientModule
],
entryComponents: [SliderComponent],
})
Импорт и использование модуля createCustomElement
Здесь нам нужно использовать модуль createCustomElement
из @angular/elements.
Вам нужно использовать SliderComponent,
в качестве параметра функции createCustomElement
. После этого нам нужно зарегистрировать slider
в DOM.
import { createCustomElement } from '@angular/elements';
export class AppModule {
constructor(private injector: Injector) {
const slider = createCustomElement(SliderComponent, { injector });
}
}
Чтобы зарегистрировать ползунок как элемент DOM, мы определим его с помощью метода customElements.define
.
customElements.define('motley-slider', slider);
Наконец, мы должны загрузить этот пользовательский элемент с помощью ngDoBootstrap()
. Полный код будет выглядеть так:
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() {}
}
Упаковка углового элемента
Нам нужно изменить package.json
с нашими новыми командами, мы изменим объект скрипта внутри файла package.json
.
Давайте проверим наш измененный объект скрипта:
"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"
}
Теперь мы можем запустить команду ng build & ng package
и, наконец, запустим ng serve для обслуживания папки dist/, сгенерированной с помощью команды build. Кроме того, мы можем использовать gzip
, полученный из команды ng package
, извлечь его и опубликовать как npm module
.