Создание плагина управления данными с интеграцией фронтенда и бэкенда
Предыдущие примеры были либо чисто клиентские (блок, поле, действие), либо клиентские + простой API (страница настроек). Этот пример показывает более полноценный сценарий — сервер определяет таблицу данных, клиент наследует TableBlockModel, чтобы получить полные возможности таблицы, плюс пользовательский компонент поля и пользовательскую кнопку действия — образуя плагин управления данными с CRUD-операциями.
Этот пример объединяет изученные ранее блок, поле и действие, демонстрируя процесс разработки полноценного плагина.
Рекомендуется сначала ознакомиться со следующим — это упростит разработку:
- Написание первого плагина — создание плагина и структура каталогов
- Plugin (Плагин) — точка входа плагина и жизненный цикл
load() - FlowEngine → Расширение блоков — BlockModel, CollectionBlockModel, TableBlockModel
- FlowEngine → Расширение полей — ClickableFieldModel, bindModelToInterface
- FlowEngine → Расширение действий — ActionModel, ActionSceneEnum
- i18n Интернационализация — формат файлов перевода и использование
tExpr() - Обзор серверной разработки — основы серверных плагинов
Конечный результат
Мы делаем плагин управления данными «Список дел» со следующими возможностями:
- Сервер определяет таблицу
todoItems, при установке плагина автоматически записываются данные-примеры - Клиент наследует
TableBlockModel, готовый к использованию блок таблицы (столбцы полей, пагинация, панель действий и т.д.) - Пользовательский компонент поля — рендерит поле priority цветным Tag
- Пользовательская кнопка действия — кнопка «Создать задачу», по клику открывает модальное окно с формой для создания записи
Полный исходный код см. в @nocobase-example/plugin-custom-table-block-resource. Если хотите запустить и посмотреть локально:
Ниже шаг за шагом построим этот плагин с нуля.
Шаг 1: создать каркас плагина
Выполните в корне репозитория:
Подробное описание см. в Написание первого плагина.
Шаг 2: определить таблицу данных (сервер)
Создайте src/server/collections/todoItems.ts. NocoBase автоматически загружает определения collection из этого каталога:
В отличие от примера со страницей настроек, здесь не нужно вручную регистрировать ресурс — NocoBase автоматически генерирует стандартные CRUD-интерфейсы (list, get, create, update, destroy) для каждой collection.
Шаг 3: настроить права доступа и данные-примеры (сервер)
Отредактируйте src/server/plugin.ts: в load() настройте права ACL, в install() вставьте данные-примеры:
Несколько ключевых моментов:
acl.allow()—['list', 'get', 'create', 'update', 'destroy']открывает полные права на CRUD;'loggedIn'означает, что доступ имеет любой авторизованный пользовательinstall()— выполняется только при первой установке плагина, подходит для записи начальных данныхthis.db.getRepository()— получение объекта операций над данными по имени collection- Не нужно
resourceManager.define()— NocoBase автоматически генерирует CRUD-интерфейсы для collection
Шаг 4: создать модель блока (клиент)
Создайте src/client-v2/models/TodoBlockModel.tsx. Наследование TableBlockModel сразу даёт полные возможности блока таблицы — столбцы полей, панель действий, пагинацию, сортировку и т.д., — не нужно писать renderComponent самостоятельно.

В реальной разра ботке плагинов, если кастомизация TableBlockModel не требуется, можно вообще не наследовать и не регистрировать этот блок — пользователю достаточно при добавлении блока выбрать «Таблица». В этой статье TodoBlockModel написан как наследник TableBlockModel для демонстрации процесса определения и регистрации модели блока. TableBlockModel обработает всё остальное (столбцы полей, панель действий, пагинацию и т.д.).
Через filterCollection ограничиваем доступность этого блока только для таблицы todoItems — при добавлении пользователем блока «Todo block» в списке выбора таблиц данных будет отображаться только todoItems, а не другие нерелевантные таблицы.

Шаг 5: создать пользовательский компонент поля (клиент)
Создайте src/client-v2/models/PriorityFieldModel.tsx. Рендерим поле priority цветным Tag — это намного нагляднее обычного текста:

После регистрации в настройках столбца priority в выпадающем меню «Компонент поля» можно будет переключиться на «Priority tag».
Шаг 6: создать пользовательскую кнопку действия (клиент)
Создайте src/client-v2/models/NewTodoActionModel.tsx. По клику на кнопку «Создать задачу» через ctx.viewer.dialog() открывается модальное окно — после заполнения формы создаётся запись:

Несколько ключевых моментов:
ActionSceneEnum.collection— кнопка появляется в панели действий вверху блокаon: 'click'— черезregisterFlowслушается событиеclickкнопкиctx.viewer.dialog()— встроенная в NocoBase возможность модального окна.contentпринимает функцию, через параметрviewможно вызыватьview.close()для закрытия окнаresource.create(values)— вызов интерфейса create таблицы данных для создания записи; после создания таблица автоматически обновляетсяobservable+observer— реактивное управление состоянием от flow-engine вместоuseState; компонент будет автоматически реагировать на измененияformState.loading
Шаг 7: добавить файлы локализации
Отредактируйте файлы перевода в src/locale/ плагина:
При первом добавлении файла языка нужно перезапустить приложение, чтобы он вступил в силу.
О формате файлов перевода и других способах использования tExpr() подробнее см. в i18n Интернационализация.
Шаг 8: зарегистрировать в плагине (клиент)
Отредактируйте src/client-v2/plugin.tsx. Нужно сделать две вещи: зарегистрировать модели и зарегистрировать todoItems в клиентском источнике данных.
Ручная регистрация таблицы данных через addCollection в коде плагина — редкий приём, здесь он используется только для демонстрации полного процесса интеграции фронтенда и бэкенда. В реальных проектах таблицы данных обычно создаются и настраиваются пользователем в интерфейсе NocoBase или управляются через API / MCP, и явная регистрация в клиентском коде плагина не нужна.
Таблица, определённая через defineCollection, является внутренней серверной таблицей и по умолчанию не появляется в списке выбора таблиц данных в блоке. После ручной регистрации через addCollection пользователь сможет выбрать todoItems при добавлении блока.

Несколько ключевых моментов:
registerModelLoaders— ленивая регистрация трёх моделей: блок, поле, действиеthis.app.eventBus— шина событий уровня приложения для прослушивания событий жизненного цикла- Событие
dataSource:loaded— срабатывает после загрузки источника данных. ВызватьaddCollectionнужно именно в обработчике этого события, потому чтоensureLoaded()выполняется послеload(), очищая и заново устанавливая все collection — прямой вызовaddCollectionвload()будет перезаписан addCollection()— регистрация collection в клиентском источнике данных. Поля должны иметь свойстваinterfaceиuiSchema, чтобы NocoBase знал, как их рендеритьfilterTargetKey: 'id'— обязательно, указывает поле, уникально идентифицирующее запись (обычно первичный ключ). Без этого collection не появится в списке выбора таблиц данных в блоке- Серверный
defineCollectionотвечает за создание физической таблицы и ORM-маппинг, клиентскийaddCollection— за то, чтобы UI знал о существовании этой таблицы. Только их совместное применение обеспечивает интеграцию фронтенда и бэкенда
Шаг 9: включить плагин
После включения:
- Создайте новую страницу, нажмите «Добавить блок», выберите «Todo block», привяжите таблицу
todoItems - Таблица автоматически загрузит данные, отобразит столбцы полей, пагинацию и т.д.
- В «Настройка действий» добавьте кнопку «New todo» — по клику откроется модальное окно с формой для создания записи
- В «Компонент поля» столбца priority переключитесь на «Priority tag» — priority будет отображаться цветным Tag

