Создание элемента слайдера изображения с использованием Angular

1. Введение

Приглашенный автор Аюш Арора

Angular Elements — это компоненты Angular, упакованные как пользовательские элементы. В настоящее время они поддерживаются Chrome, Opera и Safari и доступны в других браузерах через полифиллы. Эти элементы могут использовать всю инфраструктуру Angular с общим интерфейсом Angular и стратегией обнаружения изменений. После регистрации эти элементы можно использовать в браузере.

Эта лабораторная работа проведет вас через создание вашего собственного компонента angular слайдера изображений, а затем поможет вам преобразовать его в элемент angular, чтобы он мог работать вне Angular Framework.

Что вы будете строить

В этой кодовой лаборатории вы собираетесь создать элемент слайдера изображения, используя angular. Ваш элемент с:

  • работать как элемент HTML в браузере
  • Возможность подключения к любому фреймворку, который общается с DOM.

Что вы узнаете

  • Как сделать пользовательский компонент слайдера изображений
  • Как преобразовать пользовательский компонент слайдера изображения в пользовательский элемент
  • Как упаковать компонент, чтобы он работал внутри браузера

Что вам понадобится

  • Последняя версия angular-cli .
  • Пример кода
  • Текстовый редактор
  • Базовые знания компонентов Angular.

Эта лаборатория кода ориентирована на Angular Elements. Нерелевантные концепции и блоки кода замалчиваются и предоставляются для простого копирования и вставки.

2. Настройка

Скачать код

Щелкните следующую ссылку, чтобы загрузить весь код для этой лаборатории кода:

Распакуйте загруженный zip-файл. Это распакует корневую папку (angular-element-codelab-master) , содержащую

две папки (image-slider) и (image-slider-finished) . Мы будем выполнять всю нашу работу по кодированию в каталоге с именем image-slider.

Запуск проекта

Для запуска проекта нужно запустить команду (ng-serve) из корневого каталога (image-slider).

Как только приложение загрузится, вы сможете увидеть это:

19ffd082e2f024a5.png

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 .