Всем привет, меня зовут Дэн, я молодой веб-разработчик, увлеченный JavaScript. Сейчас я разработчик на стороне интерфейса и делаю волшебные вещи в Angular 5. Эта статья адресована новичкам, это мой первый урок по программированию, особенно - Как создавать загрузчик изображений, который вы сможете использовать в любом следующем проекте. Хорошо, поехали.
Создать новый компонент
Обычно этот компонент должен быть помещен в общий модуль, потому что вы должны получить к нему доступ глобально.
ng g c image-uploader
Создать простой загрузчик изображений
После создания компонента откройте image-uploader.component.html и создайте простой ввод.
<input type="file" id="uploader"/>
В моем случае загрузчик - это простой значок, расположенный по центру родительского блока. Я использую значок FontAwesome (вы можете заменить его любым изображением или текстом) и любые простые стили.
<label class="uploader-circle"> <i class="fas fa-plus"></i> <input type="file" id="uploader"/> </label>
ДОПОЛНИТЕЛЬНО: если вы хотите использовать значок FontAwesome, импортируйте эту библиотеку в index.html.
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/all.css" integrity="sha384-3AB7yXWz4OeoZcPbieVW64vVXEwADiYyAEhwilzWsLw+9FgqpyjjStpPnpBO8o8S" crossorigin="anonymous">
Откройте image-uploader.component.scss и добавьте следующие стили:
input { display: none; } label.uploader-circle { $size: 23px; cursor: pointer; width: $size; height: $size; line-height: 19px; text-align: center; border-radius: 100%; // Using position attribute position: absolute; // Give absolute position top: 50%; // Vertical center left: 50%; // Horizontal center transform: translate(-50%, -50%); // The icon is centered by the style regardless of the size of the parent transition: all .2s ease-out; i { font-size: 24px; color: #000; } }
Теперь наш загрузчик изображений выглядит так:
Создание функционала и подключение API
Прежде всего, мы используем HttpClient для запроса, для этого мы импортируем HttpClientModule. Для дальнейшего использования компонента мы его экспортируем.
import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {HttpClientModule} from '@angular/common/http'; // Import Path @NgModule({ imports: [ CommonModule, HttpClientModule // Import HttpClientModule ], declarations: [ ImageUploaderComponent ], exports: [ ImageUploaderComponent // Export Image Uplaoder ], providers: [] }) export class SharedModule { }
Во-вторых, откройте image-uploader.component.ts и импортируйте в конструктор HttpClient.
import {Component} from '@angular/core'; import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-image-uploader', templateUrl: './image-uploader.component.html', styleUrls: ['./image-uploader.component.scss'] }) export class ImageUploaderComponent { constructor(private http: HttpClient) { } }
Создайте метод, который получит параметры загрузчика:
import {Component} from '@angular/core'; import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-image-uploader', templateUrl: './image-uploader.component.html', styleUrls: ['./image-uploader.component.scss'] }) export class ImageUploaderComponent { selectedFile: File = null; constructor(private http: HttpClient) { } /** * Validate uploader params * @param event */ public onFileSelected(event) { this.selectedFile = <File>event.target.files[0]; if (this.selectedFile) { // If selected file exist make upload request } } }
Вызовите этот метод при изменении параметров загрузчика и отправьте $ event.
<label class="uploader-circle"> <i class="fas fa-plus"></i> <input type="file" (change)="onFileSelected($event)" id="uploader"/> </label>
ДОПОЛНИТЕЛЬНО: если мы хотим, чтобы загрузчик загружал только изображение, мы используем атрибут input accept.
<input type="file" (change)="onFileSelected($event)" accept="image/*" id="uploader"/>
Отправить запрос на сервер на загрузку изображения.
import {Component} from '@angular/core'; import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-image-uploader', templateUrl: './image-uploader.component.html', styleUrls: ['./image-uploader.component.scss'] }) export class ImageUploaderComponent { selectedFile: File = null; public image: any; constructor(private http: HttpClient) { } /** * Validate uploader params * @param event */ public onFileSelected(event) { this.selectedFile = <File>event.target.files[0]; if (this.selectedFile) { return this.upload(); } } /** * Upload image to server and receive image object */ upload() { const fd = new FormData(); fd.append('image', this.selectedFile, this.selectedFile.name); this.http.post('http://example.com/upload/image', fd).subscribe((res: any) => { this.image = res.data; }, (err: any) => { // Show error message or make something. }); } }
В нашем случае, если все в порядке, наш запрос возвращает нам следующий ответ:
Последнее, что нам нужно сделать, это вернуть ответ в нашу форму. Давайте сделаем это с помощью Angular Output. Это означает, что каждый раз, когда мы загружаем изображение, мы получаем ответ от сервера на форму.
import {Component, EventEmitter, Output} from '@angular/core'; import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-image-uploader', templateUrl: './image-uploader.component.html', styleUrls: ['./image-uploader.component.scss'] }) export class ImageUploaderComponent { selectedFile: File = null; @Output() event = new EventEmitter(); public image: any; constructor(private http: HttpClient) { } /** * Validate uploader params * @param event */ public onFileSelected(event) { this.selectedFile = <File>event.target.files[0]; if (this.selectedFile) { return this.upload(); } } /** * Upload image to server and receive image object */ upload() { const fd = new FormData(); fd.append('image', this.selectedFile, this.selectedFile.name); this.http.post('http://example.com/upload/image', fd).subscribe((res: any) => { this.image = res.data; this.event.emit(this.image); }, (err: any) => { // Show error message or make something. }); } }
Как мы используем загрузчик изображений
Когда у нас есть форма с загрузчиком изображений, мы просто ее используем.
<form> <input type="text" placeholder="Name" /> <div class="uploader"> <app-image-uploader (event)="giveImage($event)"></app-image-uploader> </div> </form>
Примечание: родительский элемент загрузчика изображения должен иметь position: relative;
В методе giveImage мы получаем ответ от загрузчика изображений ..
public giveImage(event) { console.log(event); }
Конечный результат
Вывод
Если мы создадим загрузчик как отдельный компонент, мы сможем использовать его в любой форме, которую мы используем. Его легко поддерживать и добавлять новые функции.
Спасибо за внимание, ждем ваших отзывов.