Иногда нам нужно разрешить пользователям загружать файлы, просто перетаскивая их в какую-либо область. Как это сделать в приложении Angular?

Давайте создадим новое приложение Angular с Angular Material и Flex-Layout, выполнив следующие команды:

npm install -g @angular/cli
ng new file-uploader --routing=true --style=scss
cd file-uploader
npm install @angular/flex-layout
ng add @angular/material
ng serve -o

Приложение будет доступно по адресу localhost: 4200.

Мы хотим, чтобы в нашем пользовательском интерфейсе была как стилизованная область перетаскивания, так и кнопка для выбора файлов обычным способом. Итак, давайте создадим пользовательский интерфейс без каких-либо функций:

ng g component file-uploader

Нам нужно обновить app.module.ts файл, чтобы импортировать все необходимые модули:

// app.module.ts
imports: [
…
MatButtonModule,
MatIconModule,
FlexLayoutModule
]

Обновите file-uploader.component.html и file-uploader.component.scss:

Добавьте компонент загрузки файлов в app.component.html, заменив его содержимое следующим:

<app-file-uploader></app-file-uploader>

Сейчас здесь ничего не работает, поэтому давайте добавим функциональность.

Добавьте следующий код в file-uploader.component.ts:

Обновите div.drop-area, привязав методы к событиям перетаскивания:

Что делает этот код?

Во-первых, когда файлы входят в область перетаскивания или выходят за нее, мы изменяем значение переменной isDraggedOver на значение true и устанавливаем значение false, если файлы находятся за пределами этой области. Когда isDraggedOver истинно, область выделяется путем добавления к ней класса drop-area__active.

Во-вторых, мы предотвратили загрузку или отображение файлов в браузере при их перетаскивании на страницу, вызвав наш метод stopDefault в handleDrop и handleDragOver методы. Когда происходит событие перетаскивания, список файлов сохраняется в event.dataTransfer.files. Обратите внимание, что эта переменная является типом FileList, и чтобы преобразовать ее в тип File [], мы используем статический метод Array.from.

Теперь давайте добавим функциональности нашей кнопке. Добавьте метод в компонент FileUploader:

Обновите элемент ввода, добавив к нему следующее:

И добавляем к кнопке событие нажатия:

Теперь нажатие кнопки вызовет щелчок элемента ввода. Когда файлы выбраны, мы обновляем свойство файлов с выбранными файлами.

Мы могли бы добавить эмиттер событий для нашего компонента, чтобы уведомлять родительский компонент о том, что файлы были выбраны, добавив этот код в компонент FileUploader:

@Output() filesLoaded = new EventEmitter<File[]>();

и добавив этот фрагмент в методы handleDrop и onFileChange:

this.filesLoaded.emit(this.files);

Резюме

Мы создали область перетаскивания с кнопкой, чтобы пользователи могли выбирать файлы с помощью функции перетаскивания в дополнение к обычному выбору файлов.

Все файлы доступны в репозитории GitHub, включая компонент для отображения изображений из загруженных файлов.



Ссылка на демонстрацию: https://stackblitz.com/github/orlyohreally/file-uploader.