Работа с файлами
В этом примере покажем, как создать приложение для управления изображениями. После ознакомления с этой статьей Вы научитесь загружать, сохранять, отображать и управлять изображениями.
Основные шаги
Импорт библиотек
Импортируем модули attachMedia, refresh из @app/ui и Heap из @app/heap.
import {attachMedia, refresh} from '@app/ui'
import {Heap} from '@app/heap'
attachMediaпозволяет прикреплять медиафайлыrefreshобновляет экран.Heapиз@app/heapиспользуется для работы с базой данных.
Создание таблицы
const ImagesTable = Heap.Table('images', {
filename: Heap.String(),
image: Heap.ImageFile(),
sessionId: Heap.String(),
})
ImagesTableопределяет структуру таблицы с полями:filename, в котором отображается название файлаimage- файл изображенияsessionId- идентификатор сессии, в которой будут размещаться будущие загруженные файлы.
Главный экран
Определим маршрут /, который отображает главный экран с заголовком "File manager", и на нем будут отображаться будущие файлы в виде таблицы.
app.screen('/', async (ctx, req) => {
const records = await ImagesTable.findAll(ctx, {
where: { sessionId: ctx.session.id }
})
return (
<screen title="File manager">
<text class="section">Select image file to upload</text>
{records.map(record =>
<list-item
icon={{ url: record.image.getThumbnailUrl(80) }}
content={{ title: record.filename, subTitle: record.createdAt.toLocaleDateString() }}
onClick={cardRoute({id: record.id}).navigate()}
/>
)}
ctxиreq— контекст и запрос, используемые для обработки данных.ImagesTable.findAll извлекает все записи изображений для текущей сессии.screenсоздает экран с заголовком "File manager".textвыводит текст "Select image file to upload".records.mapперебирает все записи и создает элементы списка list-item с иконкой изображения, заголовком и датой создания.
<button class={['section', 'primary']}
onClick={attachMedia({
mediaType: 'photo',
submitUrl: uploadRoute.url()
})}
>Upload</button>
</screen>
)
})
- Добавим кнопку "Upload", которая вызывает функцию
attachMediaдля загрузки изображения. При нажатии на кнопку открывается диалоговое окно для выбора фотографии, а затем вызывается маршрут загрузкиuploadRoute.
Маршрут загрузки
На данном этапе определяется маршрут /upload, который обрабатывает загрузку изображений.
const uploadRoute = app.apiCall('/upload', async(ctx, req) => {
await ImagesTable.create(ctx, {
filename: req.body.file.name,
image: req.body.file.hash,
sessionId: ctx.session.id,
})
return refresh()
})
uploadRoute— это API-запрос для загрузки изображений.ImagesTable.createсоздает новую запись в таблице с данными о загруженном файле.
После успешной загрузки и сохранения изображения, для того чтобы новый файл отобразился на экране вызывается функция refresh, которая обновляет текущий экран.
Карточка изображения
Для того чтобы отобразить отдельное изображение, нужно определить маршрут /card/:id.
const cardRoute = app.screen('/card/:id', async(ctx, req) => {
const record = await ImagesTable.getById(ctx, req.params.id)
return <screen title={record.filename}>
<image src={record.image.getThumbnailSrc(800)} />
<button class={['section', 'secondary']} onClick={ctx.router.navigate('/')}>Back</button>
</screen>
})
Тут мы определяем экран для маршрута /card/:id. Далее, используя ImagesTable.getById(ctx, req.params.id) получаем запись из таблицы ImagesTable по идентификатору, переданному в URL и отображаем экран с заголовком, соответствующим имени файла изображения (screen title={record.filename}). С помощью image src={record.image.getThumbnailSrc(800)} вставим изображение с шириной 800 пикселей. Так же добавим кнопку "Back", которая возвращает пользователя на главный экран (button c ctx.router.navigate('/')).
Заключение
Этот код демонстрирует создание таблицы для хранения изображений, определение маршрутов для отображения и загрузки изображений, а также создание динамических интерфейсов для управления этими изображениями.
Итоговый код
