Недавно мне предложили быстро создать галерею изображений. Ключевыми требованиями для этого упражнения были использование 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 .
В следующей статье мы перейдем на следующий уровень, добавив функцию бесконечной прокрутки, загружая новые изображения, когда пользователь прокручивает страницу вниз.