Недавно мне предложили быстро создать галерею изображений. Ключевыми требованиями для этого упражнения были использование Angular 8 и Bootstrap 4. В этой статье я объяснил, как мы можем достичь этого с минимальными затратами времени, усилий и ресурсов. Поскольку это практический пример использования во многих приложениях, я надеюсь, что это поможет разработчикам, пытающимся создать подобную функцию.
Обратите внимание, что для этого урока я использовал код Visual Studio на компьютере с Windows. Однако вы можете следовать за любой средой и IDE, которые поддерживают разработку приложений Angular.
Выбор источника изображения
Для этого урока давайте использовать общедоступный канал изображений из Flickr.
Этот API предоставляет изображения со связанной информацией о загрузчике, дате загрузки и многом другом, которое мы можем использовать для создания нашего приложения.
Вам также могут понравиться: Bootstrap 4 и Angular: руководство для начинающих по настройке темы
Создание углового проекта
Откройте командную строку и перейдите в каталог, в котором вы хотите создать проект, и введите ng newкоманду.
Здесь я создал новый Angular проект с названием image-gallery. Вы можете назвать свой проект по своему вкусу. Выберите «Нет» для добавления Угловой маршрутизации и CSS в качестве формата таблицы стилей и нажмите Enter, чтобы создать проект.
Очистка и первоначальная настройка
Как только проект создан, откройте его в вашей любимой IDE. В окне встроенного терминала введите ng serveкоманду, чтобы убедиться, что проект работает нормально и работает без проблем. По умолчанию Angular запускает приложение по адресу http: // localhost: 4200 / .
На этом этапе, если вы откроете приложение, используя локальный URL-адрес, вы увидите содержимое app.component.html на странице. Этот контент является шаблонным шаблоном, введенным Angular. Идите и удалите все из этого файла.
Мы будем отображать имя приложения, используя свойство title app.component.ts. Измените заголовок, чтобы отобразить подходящее имя для вашего приложения.
Машинопись
1
import { Component } from '@angular/core';
2
@Component({
4
selector: 'app-root',
5
templateUrl: './app.component.html',
6
styleUrls: ['./app.component.css']
7
})
8
export class AppComponent {
9
title = 'flickr image-gallery';
10
}
11
Теперь в app.component.html отобразите этот заголовок внутри H1, используя интерполяцию строк.
<h1>{{title}}</h1>
На данный момент вы должны увидеть это в вашем браузере.
Мы улучшим это, добавив необходимые сервисы и компоненты.
Создание сервиса Flickr
Чтобы вызвать API Flickr и получить изображения, нам понадобится сервис. Мы можем поручить Angular CLI создать для нас сервис, введя ng generate service flickrкоманду в терминале.
Теперь давайте потратим некоторое время на анализ необработанного ответа от Flickr API . Мы можем увидеть необработанный ответ, просто выполнив запрос get в браузере.
Обратите внимание, что ответ обернут внутри jsonFlickrFeed. Однако нам нужен простой JSON для работы. Мы можем получить ответ JSON, используя дополнительный параметр строки запросаnojsoncallback=1.
Нам также нужно подумать о способе десериализации сложного ответа JSON на подходящий тип машинописи. Это облегчит работу с ответом. Мы также получим машинописный текст IntelliSense при написании выражений привязки для отображения изображений и соответствующей информации.
Давайте добавим папку моделей в папку приложения для хранения интерфейсов, которые мы использовали бы для десериализации ответа JSON. Для сложных подтипов мы добавим отдельные интерфейсы.
Машинопись
xxxxxxxxxx
1
export interface MediaUrl {
2
m: string;
3
}
Машинопись
xxxxxxxxxx
1
import { MediaUrl } from './MediaUrl';
2
export interface Item {
4
title: string;
5
link: string;
6
media: MediaUrl;
7
date_taken: Date;
8
description: string;
9
published: Date;
10
author: string;
11
author_id: string;
12
tags: string;
13
}
Машинопись
xxxxxxxxxx
1
import { Item } from './Item';
2
export interface FlickerResponse {
4
title: string;
5
link: string;
6
description: string;
7
modified: Date;
8
generator: string;
9
items: Item[];
10
}
Обратите внимание, как определяется интерфейс FlickerResponse. Помимо простых свойств, он также включает в себя элементы свойств типа Item array. Сам элемент представляет собой интерфейс со своими собственными свойствами. Вы можете следовать этому подходу для десериализации сложных ответов API.
Давайте теперь перейдем к реализации сервиса. Это на самом деле просто. Мы будем использовать HttpClientModule от Angular для выдачи запроса на получение API.
Машинопись
xxxxxxxxxx
1
import { Injectable } from '@angular/core';
2
import { Observable } from 'rxjs';
3
import { FlickerResponse } from './models/flickerresponse';
4
import { HttpClient } from '@angular/common/http';
5
@Injectable({
7
providedIn: 'root'
8
})
9
export class FlickrService {
10
flickerUrl = 'https://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1';
12
constructor(private http: HttpClient) { }
14
getPhotos(): Observable<FlickerResponse> {
16
return this.http.get<FlickerResponse>(this.flickerUrl);
17
}
18
}
19
Обратите внимание, как мы возвратили Observable типа FlickerResponseиз метода сервиса getPhotos .
Мы проделали большую тяжелую работу, чтобы выйти на этот этап. Теперь пришло время увидеть некоторые результаты.
Построение галереи изображений
Чтобы отобразить изображения, давайте создадим новый компонент. Перейдите к терминалу и выполните команду создания компонента ng generate component photo-gallery.
Нам нужно добавить этот компонент в компонент приложения, так как мы будем рендерить все изображения там.
Теперь пришло время использовать FlickrService в нашей фотогалерее.
xxxxxxxxxx
1
import { Component, OnInit } from '@angular/core';
2
import { FlickerResponse } from '../models/flickerresponse';
3
import { FlickrService } from '../flickr.service';
4
@Component({
6
selector: 'app-photo-gallery',
7
templateUrl: './photo-gallery.component.html',
8
styleUrls: ['./photo-gallery.component.css']
9
})
10
export class PhotoGalleryComponent implements OnInit {
11
flickerResponse: FlickerResponse;
13
constructor(private flickrService: FlickrService) { }
15
ngOnInit() {
17
this.flickrService.getPhotos().subscribe( response => {
18
this.flickerResponse = response;
19
}, error => {
20
console.log(error);
21
});
22
}
23
}
25
Давайте поймем, что мы сделали. Мы использовали внедрение зависимостей, чтобы внедрить экземпляр FlickrService в компонент фотогалереи. Мы раскрыли частную собственность, flickrService используя которую getPhotosбыл вызван метод сервиса. Наконец, мы храним ответ на свойство flickerRespone.
Теперь, когда мы получили реальный ответ от сервиса, давайте что-нибудь отобразим в фотогалерее. Мы будем использовать это flickerResponseсвойство для перебора массива элементов и отображения изображений.
xxxxxxxxxx
1
<div *ngFor="let item of flickerResponse?.items">
2
<img [src]="item.media.m" [alt]="item.title">
3
</div>
4
При этом мы должны увидеть фотографии. Вместо этого мы видим пустую страницу только с заголовком. Давайте посмотрим, какую информацию мы можем получить из журнала консоли.
Похоже, что ответ блокируется браузером, так как он не видит элемент заголовка Access-Control-Allow-Origin в ответе. Это поведение по умолчанию для большинства браузеров. В целях безопасности браузеры блокируют совместное использование ресурсов между двумя разными доменами. Здесь, поскольку наше приложение работает на локальном хосте, и мы запрашиваем данные с сайта api.flickr.com, Chrome заблокировал ответ. Это типичный пример ошибки CORS.
Так как мы можем решить это?
Если у нас есть контроль над ресурсом API, мы можем просто добавить заголовок Access-Control-Allow-Origin с целевыми доменами, которые мы хотим добавить в белый список или * в запросы белого списка из любого источника.
В этом случае, однако, поскольку мы не можем контролировать код API, нам нужно включить CORS вручную в браузере. Теперь это угроза безопасности и должна быть отключена, как только мы закончим тестирование.
Делать это вручную может быть сложно. К счастью, есть расширение Chrome, которое позволяет нам включать или отключать CORS одним щелчком мыши. Вы можете скачать расширение из интернет-магазина Chrome.
Теперь, когда мы решили проблему с CORS, можем ли мы что-то увидеть на экране?
Ну, мы видим изображения, но мы еще не совсем там. В следующем разделе давайте добавим BootStrap и сделаем галерею похожей на галерею.
Стилизация галереи
В окне терминала используйте команду npm install bootstrap --save для установки Bootstrap в наше приложение.
После установки откройте файл styles.css из обозревателя решений и импортируйте Bootstrap в качестве нашего глобального поставщика стилей.
xxxxxxxxxx
1
/* You can add global styles to this file, and also import other style files */
2
@import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
3
С этим мы в значительной степени настроены привнести немного магии CSS и украсить наше приложение.
Давайте изменим app.component.html, как показано ниже.
xxxxxxxxxx
1
<div class="container">
2
<h1 style="text-align: center;">
3
Welcome to {{title}}
4
</h1>
5
<br>
6
<app-photo-gallery></app-photo-gallery>
7
</div>
Точно так же добавьте ниже к photo-gallery.component.html.
HTML
xxxxxxxxxx
1
<div class="card-columns">
2
<div class="card" *ngFor="let item of flickerResponse?.items">
3
<img class="card-img-top" [src]="item.media.m" [alt]="item.title" />
4
<div class="card-body">
5
<h5 class="card-title">{{ item.title }}</h5>
6
<p class="card-text">
7
Uploaded by {{ item.author_id }} on
8
{{ item.published | date: "medium" }}
9
</p>
10
<p class="card-text">{{ item.title }}</p>
11
<hr>
12
<p class="card-text">
13
<small class="text-muted">{{ item.tags }}</small>
14
</p>
15
</div>
16
</div>
17
</div>
С этим давайте посмотрим, выглядит ли наша галерея презентабельно.
Как вы видите, теперь у нас есть красивая мозаика с изображениями карт. Этот тип презентации называется макетом столбца Masonry и подходит, когда у нас есть переменные размеры изображения.
Я надеюсь, что эта статья поможет вам реализовать аналогичные функции в ваших приложениях. Вы можете скачать исходный код с Github .
В следующей статье мы перейдем на следующий уровень, добавив функцию бесконечной прокрутки, загружая новые изображения, когда пользователь прокручивает страницу вниз.