React-Admin <ImageInput>для загрузки изображений в rails api - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь загрузить изображения из response-admin в серверный rails api, используя активное хранилище.

В документации по activ-admin говорится: «Обратите внимание, что при загрузке изображения возвращается объект File. Вы отвечаете за его обработку в зависимости от поведения API. Например, вы можете кодировать его в base64 или отправить как данные из нескольких частей "Я пытаюсь отправить их как форму из нескольких частей.

Я читал здесь и там, но я не могу найти то, что хочу, по крайней мере, план действий, как мне следует действовать.

1 Ответ

0 голосов
/ 16 января 2019

Вы можете найти пример в разделе dataProvider документации.

Вы должны украсить свой dataProvider, чтобы разрешить загрузку данных. Вот пример преобразования изображений в строки base64 перед публикацией ресурса:

// in addUploadFeature.js
/**
 * Convert a `File` object returned by the upload input into a base 64 string.
 * That's not the most optimized way to store images in production, but it's
 * enough to illustrate the idea of data provider decoration.
 */
const convertFileToBase64 = file => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file.rawFile);

    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
});

/**
 * For posts update only, convert uploaded image in base 64 and attach it to
 * the `picture` sent property, with `src` and `title` attributes.
 */
const addUploadFeature = requestHandler => (type, resource, params) => {
    if (type === 'UPDATE' && resource === 'posts') {
        // notice that following condition can be true only when `<ImageInput source="pictures" />` component has parameter `multiple={true}`
        // if parameter `multiple` is false, then data.pictures is not an array, but single object
        if (params.data.pictures && params.data.pictures.length) {
            // only freshly dropped pictures are instance of File
            const formerPictures = params.data.pictures.filter(p => !(p.rawFile instanceof File));
            const newPictures = params.data.pictures.filter(p => p.rawFile instanceof File);

            return Promise.all(newPictures.map(convertFileToBase64))
                .then(base64Pictures => base64Pictures.map((picture64, index) => ({
                    src: picture64,
                    title: `${newPictures[index].title}`,
                })))
                .then(transformedNewPictures => requestHandler(type, resource, {
                    ...params,
                    data: {
                        ...params.data,
                        pictures: [...transformedNewPictures, ...formerPictures],
                    },
                }));
        }
    }
    // for other request types and resources, fall back to the default request handler
    return requestHandler(type, resource, params);
};

export default addUploadFeature;

Затем вы можете применить это к вашему провайдеру данных:

// in dataProvider.js
import simpleRestProvider from 'ra-data-simple-rest';
import addUploadFeature from './addUploadFeature';

const dataProvider = simpleRestProvider('http://path.to.my.api/');
const uploadCapableDataProvider = addUploadFeature(dataProvider);

export default uploadCapableDataProvider;

Наконец, вы можете использовать его в своем админском обычном режиме:

// in App.js
import { Admin, Resource } from 'react-admin';

import dataProvider from './dataProvider';
import PostList from './posts/PostList';

const App = () => (
    <Admin dataProvider={uploadCapableDataProvider}>
        <Resource name="posts" list={PostList} />
    </Admin>
);
...