Николай Ланец
19 июня 2019 г., 14:16

Оживляем формы во фронт-редакторе

Всем привет!

Сегодня я покажу как можно оживлять формы в prisma-cms. Только сразу уточню, что для этого уже потребуется немного попрограммировать, то есть мы будем расширять имеющийся функционал, точнее просто добавим одну кнопку.

Задача следующая: есть Услуги и есть Категории услуг. Вот надо в форму создания Услуги добавить возможность задавать Категорию. Для этого у нас практически все есть во фронт-редакторе "из коробки": EditableObject позволяет создавать/редактировать объекты, а Query+Connector позволяет в форму добавить список Категорий. Но список Категорий-то мы получим, но как нам сделать, чтобы мы могли по клику указывать эту Категорию Услуге? Для этого нам надо создать свою кнопку Категории, чтобы по клику и выполнялось нужное нам действие. Вот посмотрите как это выглядит, а ниже я покажу рабочий код и объясню его.


Итак, как вы видели в ролике, у нас обычный текстовый вывод менялся на компонент SetServiceCategory. Вот его код:
import React from 'react'; import EditorComponent from '@prisma-cms/front-editor/lib/components/App/components/'; import { Button } from 'material-ui'; import { ObjectContext } from '@prisma-cms/front-editor/lib/components/App/components/public/Connectors/Connector/ListView'; import { EditableObjectContext } from '@prisma-cms/front-editor/lib/components/App/context'; export class SetServiceCategory extends EditorComponent { static Name = 'SetServiceCategory'; renderPanelView() { const { classes, } = this.getEditorContext(); return super.renderPanelView( <div className={classes.panelButton} > SetServiceCategory </div> ); } canBeChild(child) { return false; } renderChildren() { return <ObjectContext.Consumer> {context => { const { object, ...otherContext } = context; if (!object) { return null; } let output = null; const { id: objectId, name, } = object; if (!objectId) { return null; } output = <EditableObjectContext.Consumer> {editableObjectContext => { const { updateObject, getEditor, inEditMode, canEdit, getObjectWithMutations, } = editableObjectContext; const object = getObjectWithMutations(); if (!object) { return null; } const { Category, } = object; const categoryId = Category ? (Category.id || (Category.connect && Category.connect.id)) : null; return getEditor({ Editor: (props) => { return <Button size="small" variant={categoryId && categoryId === objectId ? "raised" : undefined} onClick={event => { updateObject({ Category: { connect: { id: objectId, }, }, }); }} > {name} </Button> }, }); }} </EditableObjectContext.Consumer> return output; }} </ObjectContext.Consumer>; } } export default SetServiceCategory;
Про основные моменты, касающиеся базового компонента фронт-редактора, написано здесь: Добавление кастомных компонентов в @prisma-cms/front-editor. Так же напомню, что есть специальное расширение для редактора VS Code: Расширение prisma-cms для редактора VS Code. Ускоряем процесс программирования.

А мы сосредоточимся сейчас на самом главном - методе renderChildren(), который и выводит нашу новую кнопку. Саму кнопку найти в этом коде не сложно, но нам важнее разобраться с ее обертками - ObjectContext.Consumer и EditableObjectContext.Consumer.

ObjectContext.Consumer позволяет получить данные текущего объекта. В нашем случае это объект Категория на каждой итерации вывода данных Категорий, полученных в запросе. Подробнее об этом читайте пор ObjectView и ListView.

EditableObjectContext.Consumer позволяет получить данные редактируемого объекта, и не только данные, но и методы создания редактируемых полей, проверки может ли быть объект редактируемым, его измененные данные и метод обновления его данных. Читайте подробней про EditableObject.

Таким образом, на каждой итерации вывода массива Категорий, мы получаем данные этой Категории (id и name) и проверяем выбрана эта Категория или нет (если выбрана, кнопку делаем жирной). А по клику через updateObject(), полученный из EditableObjectContext.Consumer, мы обновляем наш объект Услуги, то есть задаем ей Категорию. Здесь следует четко понимать, что на самом деле мы еще не обновляем в этот момент Услугу, а только задаем ей новое свойство. При этом Услуга еще в режиме Черновик. Реальное же обновление будет выполнено по клику на кнопку Сохранить (красная дискета), вот тогда данные будут отправлены на сервер, и если все ОК, то Услуга будет сохранена.

Добавить комментарий