Файлы (Files)
Поле типа Файлы позволяет загружать и хранить несколько файлов любого типа.
Основные характеристики
- Количество файлов: Множественные файлы
- Максимальное количество: Настраивается (по умолчанию без ограничений)
- Максимальный размер: Настраивается для каждого файла
- Типы файлов: Любые (с возможностью ограничения)
- Хранение: В интегрированном хранилище EMD Cloud
- Порядок: Поддержка сортировки файлов
Настройки поля
При создании поля типа "Файлы" доступны следующие настройки:
- Название поля: Отображаемое имя поля
- Системное имя: Уникальный идентификатор для API
- Описание: Подсказка для пользователей
- Обязательное поле: Требовать загрузки хотя бы одного файла
- Минимальное количество: Минимальное количество файлов
- Максимальное количество: Максимальное количество файлов
- Максимальный размер: Ограничение размера каждого файла (в МБ)
- Допустимые типы: Ограничение по типам файлов (MIME types)
- Автоматическое превью: Генерировать превью для изображений
Примеры использования
Галерея товара
{
"name": "images",
"type": "files",
"required": true,
"minFiles": 1,
"maxFiles": 10,
"maxSize": 5,
"allowedTypes": ["image/jpeg", "image/png", "image/webp"]
}
Документы проекта
{
"name": "documents",
"type": "files",
"maxFiles": 20,
"allowedTypes": [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
]
}
Вложения к задаче
{
"name": "attachments",
"type": "files",
"maxSize": 10
}
Работа через API
Загрузка нескольких файлов
// Загрузка файлов по одному
const uploadedFiles = [];
for (const file of fileInput.files) {
const formData = new FormData();
formData.append('file', file);
const uploaded = await emd.storage.upload(formData);
uploadedFiles.push(uploaded.id);
}
// Создание записи с файлами
const record = await emd.database.collection('products').create({
name: 'Ноутбук Dell XPS 15',
images: uploadedFiles
});
Загрузка с созданием записи
const formData = new FormData();
formData.append('name', 'Ноутбук Dell XPS 15');
// Добавление нескольких файлов
for (const file of fileInput.files) {
formData.append('images', file);
}
const record = await emd.database.collection('products').create(formData);
Получение списка файлов
const record = await emd.database.collection('products').get(recordId);
console.log(record.images);
// [
// {
// id: "file_123",
// name: "front.jpg",
// size: 245678,
// mimeType: "image/jpeg",
// url: "https://cdn.emd.one/files/file_123.jpg",
// order: 0
// },
// {
// id: "file_124",
// name: "back.jpg",
// size: 198765,
// mimeType: "image/jpeg",
// url: "https://cdn.emd.one/files/file_124.jpg",
// order: 1
// }
// ]
Добавление файлов к существующей записи
// Получить текущие файлы
const record = await emd.database.collection('products').get(recordId);
// Загрузить новый файл
const formData = new FormData();
formData.append('file', newFile);
const uploaded = await emd.storage.upload(formData);
// Добавить к существующим
await emd.database.collection('products').update(recordId, {
images: [...record.images.map(f => f.id), uploaded.id]
});
Удаление файла из списка
const record = await emd.database.collection('products').get(recordId);
// Удалить файл с определенным ID
const fileIdToRemove = 'file_123';
const updatedFiles = record.images
.filter(f => f.id !== fileIdToRemove)
.map(f => f.id);
await emd.database.collection('products').update(recordId, {
images: updatedFiles
});
// Опционально: удалить файл из хранилища
await emd.storage.delete(fileIdToRemove);
Изменение порядка файлов
const record = await emd.database.collection('products').get(recordId);
// Переставить файлы местами
const reorderedFiles = [
record.images[2].id,
record.images[0].id,
record.images[1].id
];
await emd.database.collection('products').update(recordId, {
images: reorderedFiles
});
Работа с галереями изображений
Получение превью
const record = await emd.database.collection('products').get(recordId);
// Первое изображение (главное)
const mainImage = record.images[0];
const mainImageUrl = mainImage.url;
const mainImageThumb = mainImage.thumbnails.medium;
// Все превью для галереи
const gallery = record.images.map(img => ({
original: img.url,
thumbnail: img.thumbnails.small,
title: img.name
}));
Отображение галереи в HTML
const record = await emd.database.collection('products').get(recordId);
const galleryHTML = record.images.map(img => `
<div class="gallery-item">
<img src="${img.thumbnails.medium}" alt="${img.name}" />
</div>
`).join('');
document.getElementById('gallery').innerHTML = galleryHTML;
Массовые операции
Загрузка множества файлов с прогрессом
const files = Array.from(fileInput.files);
const uploadedFiles = [];
for (let i = 0; i < files.length; i++) {
const formData = new FormData();
formData.append('file', files[i]);
const uploaded = await emd.storage.upload(formData, {
onProgress: (progress) => {
console.log(`Файл ${i + 1}/${files.length}: ${progress}%`);
}
});
uploadedFiles.push(uploaded.id);
}
await emd.database.collection('products').update(recordId, {
images: uploadedFiles
});
Удаление всех файлов
const record = await emd.database.collection('products').get(recordId);
// Удалить все файлы из хранилища
for (const file of record.images) {
await emd.storage.delete(file.id);
}
// Очистить поле
await emd.database.collection('products').update(recordId, {
images: []
});
Поиск по файлам
Найти записи с файлами
// Записи, у которых есть хотя бы один файл
const records = await emd.database.collection('products').find({
images: { $exists: true, $ne: [] }
});
// Записи с определенным количеством файлов
const records = await emd.database.collection('products').find({
'images.$size': 5
});
Валидация
Ограничение количества файлов
{
"name": "images",
"type": "files",
"minFiles": 3,
"maxFiles": 10
}
Проверка при создании
try {
const record = await emd.database.collection('products').create({
name: 'Товар',
images: uploadedFiles
});
} catch (error) {
if (error.code === 'MIN_FILES_REQUIRED') {
console.error('Загрузите минимум 3 изображения');
}
if (error.code === 'MAX_FILES_EXCEEDED') {
console.error('Максимум 10 изображений');
}
}
Оптимизация производительности
Ленивая загрузка превью
const record = await emd.database.collection('products').get(recordId, {
fields: ['name', 'images.id', 'images.thumbnails.small']
});
Пагинация файлов
Для записей с большим количеством файлов:
const record = await emd.database.collection('documents').get(recordId);
const filesPerPage = 20;
const page = 1;
const paginatedFiles = record.attachments.slice(
(page - 1) * filesPerPage,
page * filesPerPage
);
Метаданные файлов
Каждый файл в массиве содержит:
{
id: "file_123",
name: "image.jpg",
originalName: "Фото товара.jpg",
size: 1245678,
mimeType: "image/jpeg",
url: "https://cdn.emd.one/files/file_123.jpg",
thumbnails: {
small: "...",
medium: "...",
large: "..."
},
order: 0,
uploadedAt: "2025-11-25T10:30:00Z",
uploadedBy: "user_456"
}
Рекомендации
- Устанавливайте разумные ограничения на количество файлов
- Используйте превью для изображений в списках
- Реализуйте ленивую загрузку для больших галерей
- Показывайте прогресс загрузки для множественных файлов
- Позволяйте пользователям менять порядок файлов
- Добавляйте возможность удаления отдельных файлов
- Оптимизируйте изображения перед загрузкой
- Используйте CDN для быстрой доставки файлов
Типичные сценарии
Галерея товара
- Минимум 1 изображение
- Максимум 10 изображений
- Первое изображение — главное
- Возможность изменения порядка
Документы проекта
- Без ограничения количества
- Разные типы файлов (PDF, DOC, XLS)
- Сортировка по дате загрузки
Вложения к задаче
- Без ограничения количества
- Любые типы файлов
- Возможность добавления/удаления
Отличие от других типов
- Files vs File: Files для множественных файлов, File для одного
- Files vs JSON: Files для файлов, JSON для структурированных данных
- Files vs Relation: Files для файлов, Relation для связей между записями