Загрузка файлов — одна из часто встречающихся задач при разработке веб-приложений. Angular предоставляет набор инструментов и подходов, позволяющих реализовать эту функциональность эффективно и безопасно. Основные компоненты процесса загрузки включают работу с формами, обработку событий, отправку данных на сервер и управление прогрессом.
Для начала создается форма с элементом
<input type="file">. Angular позволяет использовать
двустороннюю привязку данных и связывать выбранный файл
с переменной в компоненте:
<form (ngSubmit)="uploadFile()">
<input type="file" (change)="onFileSelected($event)" />
<button type="submit">Загрузить</button>
</form>
Ключевой момент — событие change, которое срабатывает
при выборе файла. Оно позволяет получить объект File,
который можно отправить на сервер.
В компоненте создается метод для обработки события выбора файла:
import { Component } from '@angular/core';
@Component({
selector: 'app-file-upload',
templateUrl: './file-upload.component.html'
})
export class FileUploadComponent {
selectedFile: File | null = null;
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;
if (input.files && input.files.length > 0) {
this.selectedFile = input.files[0];
}
}
}
Особенности:
File содержит имя, размер, тип и содержимое
файла.input.files && input.files.length > 0
предотвращает ошибки при отсутствии выбранного файла.Для загрузки файла используется объект FormData, который
позволяет передавать бинарные данные через HTTP-запрос:
import { HttpClient, HttpEvent, HttpEventType } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class FileUploadService {
constructor(private http: HttpClient) {}
upload(file: File) {
const formData = new FormData();
formData.append('file', file, file.name);
return this.http.post('/api/upload', formData, {
reportProgress: true,
observe: 'events'
});
}
}
Метод post принимает FormData и позволяет
отслеживать прогресс загрузки через параметр
observe: 'events'.
Для информирования пользователя о состоянии загрузки удобно
использовать обработку событий HttpEvent:
uploadFile(): void {
if (!this.selectedFile) return;
this.fileUploadService.upload(this.selectedFile).subscribe(event => {
if (event.type === HttpEventType.UploadProgress && event.total) {
const progress = Math.round((100 * event.loaded) / event.total);
console.log(`Прогресс: ${progress}%`);
} else if (event.type === HttpEventType.Response) {
console.log('Файл успешно загружен');
}
});
}
Особенности:
HttpEventType.UploadProgress возвращает
loaded и total для вычисления процента
загрузки.HttpEventType.Response сигнализирует об успешном
завершении операции.BehaviorSubject для отображения
прогресса в пользовательском интерфейсе.Angular позволяет обрабатывать несколько файлов одновременно, изменяя
атрибут multiple у <input> и расширяя
логику обработки:
<input type="file" (change)="onFilesSelected($event)" multiple />
selectedFiles: File[] = [];
onFilesSelected(event: Event): void {
const input = event.target as HTMLInputElement;
if (input.files) {
this.selectedFiles = Array.from(input.files);
}
}
Для отправки на сервер можно итерировать массив файлов и формировать
FormData для каждого или объединять их в один запрос.
Важно проверять размер и тип файлов перед отправкой:
const allowedTypes = ['image/png', 'image/jpeg'];
const maxSize = 5 * 1024 * 1024; // 5 МБ
validateFile(file: File): boolean {
return allowedTypes.includes(file.type) && file.size <= maxSize;
}
Эта проверка повышает безопасность и предотвращает ошибки на сервере.
Для более современного интерфейса можно реализовать drag-and-drop:
<div
class="drop-zone"
(drop)="onDrop($event)"
(dragover)="onDragOver($event)"
>
Перетащите файлы сюда
</div>
onDragOver(event: DragEvent) {
event.preventDefault();
}
onDrop(event: DragEvent) {
event.preventDefault();
if (event.dataTransfer?.files) {
this.selectedFiles = Array.from(event.dataTransfer.files);
}
}
Особенности:
preventDefault() нужен для корректного поведения
браузера.Важно обрабатывать ошибки сервера и сетевые сбои:
this.fileUploadService.upload(this.selectedFile).subscribe({
next: event => { /* обработка прогресса */ },
error: err => console.error('Ошибка загрузки:', err),
complete: () => console.log('Загрузка завершена')
});
Можно использовать catchError и retry из
RxJS для более надежной обработки:
import { catchError, retry } from 'rxjs/operators';
Эта структура обеспечивает надежную и гибкую систему загрузки файлов в Angular-приложениях, охватывая основные сценарии: выбор файла, валидация, прогресс, множественные файлы и drag-and-drop.