Appearance
Получение коллекций через запросы
Настройте request, чтобы панель запрашивала нужные объекты. Выбирайте способ по источнику данных: Table может показать объекты одного метатипа, связанные объекты, результат метода или произвольного HTTP-запроса. Зависимая панель может запросить один выбранный объект.
Это руководство описывает общий механизм запросов. Отдельный вариант панели может поддерживать более узкую конфигурацию или дополнять её поведение; перед переносом примера сверьтесь с руководством этого варианта.
Выбор способа запроса
| Задача | Обязательные признаки | Кто обрабатывает запрос |
|---|---|---|
| Получить объекты одного метатипа | metaTypeName | Сервер, поиск объектов |
| Получить объекты через Link | getSelectedObjectForEventId + linkName без metaTypeName | Сервер, связанные объекты |
| Найти объекты, ссылающиеся атрибутом на выбранный объект | metaTypeName + идентификатор события + linkedAttribute | Сервер, поиск по атрибуту |
| Получить один известный или выбранный объект | Потребитель передаёт ObjectSelector | Сервер |
| Использовать результат метаметода | methodName | Метод формирует коллекцию |
| Показать произвольные JSON-строки | customRequest | Сервер возвращает массив; клиент сортирует и разбивает его на страницы |
Для запроса по выбранному объекту пользователь сначала выбирает строку в панели-источнике. Её обработчик события должен выполнить addSelectedObjectToRequest: приложение сохраняет селектор выбранного объекта для события, а зависимый запрос читает его по идентификатору события. Одного объявления события без выбора строки недостаточно.
Порядок выбора
Общий механизм выбирает первое совпадение:
customRequest.methodName.- Один
objectSelector, переданный потребителем. metaTypeName+ событие выбора +linkedAttribute.- Событие выбора +
linkNameбезmetaTypeName. metaTypeName.
Оставляйте один набор признаков. Это порядок совместимости: случайно оставленный customRequest получит приоритет над metaTypeName, а метод — над признаками обычного запроса или запроса связанных объектов.
Состав ответа и пути атрибутов
Для обычного запроса и запроса через Link приложение выбирает список атрибутов:
- Явный список, переданный вызывающим потребителем.
request.attributeList.- Атрибуты непосредственных колонок панели.
Приложение удаляет повторы и заменяет точки вложенных путей на | для API. В запросе через Link путь link.quantity превращается в link:quantity; обычный запрос объектов исключает атрибуты link.*. Фильтры, сортировка и поля редактора не расширяют этот список автоматически.
Произвольный HTTP-запрос не использует такой список: приложение преобразует ключи возвращённых строк в атрибуты и учитывает columns[].dataType.
Обычный запрос
Используйте metaTypeName, если коллекцию можно запросить независимо от выбора в другой панели.
json
{
"request": {
"metaTypeName": "ProductionOrder",
"attributeList": ["code", "status", "product.name"],
"findAttributes": [
{
"field": "status",
"compareType": "EQUAL",
"value": "released"
}
],
"sortParams": [
{ "attribute": "code", "sortDirection": "ASC" }
]
},
"pagination": {
"rowsPerPage": [10, 25, 50]
}
}Первое число rowsPerPage задаёт начальный размер страницы. Из ответа Table берёт общее количество, размер и смещение для отображения страниц.
Запросы по выбранному объекту
Через Link
linkName задаёт тип Link, через который сервер находит коллекцию. Родительский объект приложение берёт из сохранённого события выбора.
json
{
"request": {
"getSelectedObjectForEventId": "order-selected",
"linkName": "OrderOperation",
"reverse": false,
"attributeList": ["code", "status", "link.sequence"]
}
}reverse по умолчанию равен false; направление меняется только при true. При отправке фильтры и сортировка по obj и link получают префиксы, которые нужны запросу связанных объектов.
Через атрибут
Если дочерний метатип хранит ссылку на родителя в атрибуте, используйте linkedAttribute. Приложение выполняет поиск объектов по этому атрибуту, а не запрос getLinkedObjects.
json
{
"request": {
"metaTypeName": "Operation",
"getSelectedObjectForEventId": "order-selected",
"linkedAttribute": "order"
}
}При каждом запросе приложение добавляет условие равенства linkedAttribute GUID выбранного объекта. Table также отправляет текущие применённые findAttributes. Reset с последующим Apply очищает эти фильтры, но сохраняет обязательное условие родителя.
Чтобы запустить этот запрос, выберите родительский объект в панели-источнике. Пока указанное событие не содержит выбранного родителя, Table не отправляет POST /Object/find для запроса через linkedAttribute. Снятие выбора очищает строки зависимой таблицы и сохраняет применённые пользовательские фильтры. При следующем выборе Table использует выбранного родителя и те же применённые фильтры.
Запрос через метод
Источник на основе метода использует те же способы указания объектов, что и действия runMethod.
json
{
"id": "local-shared-config-method-request",
"type": "table",
"request": {
"methodName": "FindLocalOrdersForAnchor",
"parent": "LocalOrder",
"objects": [
{
"objectId": {
"objectGuid": "local-order-001"
}
}
]
},
"columns": [
{ "attribute": "code", "label": "Code" },
{ "attribute": "product", "label": "Product" },
{ "attribute": "status", "label": "Status" },
{ "attribute": "priority", "label": "Priority" }
]
}Общий механизм определяет GUID из objectId и отправляет parent, methodName, массив GUID objects и пустой объект params в POST /MetaMethods/Run. Table преобразует ответ метода в строки объектов. Этот способ работает через общий механизм, хотя старое локальное описание типов Table перечисляет не все варианты. Исполнитель метода не передаёт фильтры, сортировку или параметры страниц; метод должен вернуть пригодную для показа коллекцию.
Локальный демонстрационный обработчик узнаёт именно этот метод и требует parent: "LocalOrder" вместе с local-order-001. Он возвращает три локальных заказа в формате ObjectsResponse. Имя и данные относятся к демонстрации; они не подтверждают наличие такого метода на рабочем сервере.
Произвольный HTTP-запрос
Выбирайте этот способ для строк, которые нельзя получить через обычный API объектов.
json
{
"request": {
"customRequest": {
"method": "GET",
"url": "/reports/order-progress",
"idField": "orderId",
"dataPath": "data.rows"
}
},
"pagination": {
"rowsPerPage": [10, 25]
},
"columns": [
{ "attribute": "orderId", "label": "Order", "dataType": "Guid" },
{ "attribute": "progress", "label": "Progress", "dataType": "Double" }
]
}json
{
"id": "local-shared-config-custom-request",
"type": "table",
"request": {
"customRequest": {
"method": "GET",
"url": "/applications/local-panel-fixtures/json-data",
"dataPath": "panel.panels",
"idField": "type"
}
},
"pagination": { "rowsPerPage": [1, 2] },
"columns": [
{
"attribute": "id",
"dataType": "String",
"label": "Panel ID",
"sortable": true
},
{
"attribute": "type",
"dataType": "String",
"label": "Type",
"sortable": true
},
{
"attribute": "panelLayout",
"dataType": "Json",
"label": "Size settings"
}
]
}Table отправляет запрос по url с указанным method, извлекает массив по dataPath, если путь указан, и сортирует и разбивает полный массив на страницы в клиенте. dataPath — путь через точки, не JSONPath. Table передаёт только URL и метод, без заголовков или тела запроса.
idField по умолчанию равен id. Приложение использует его значение как id, objectGuid и objectSelector.objectGuid строки. Поле должно присутствовать и быть уникальным во всём ответе, когда действия или выбор зависят от идентичности строки. Тип колонки dataType имеет приоритет; без него приложение определяет тип по значению.
Второй пример обращается к JSON-конфигурации локального приложения. panel.panels содержит две строки, а их значения type — message и table — дают уникальные идентификаторы. Размеры страниц 1 и 2 и сортируемые колонки id/type позволяют проверить обработку массива в клиенте. Не добавляйте в этот пример заголовки или тело: текущий исполнитель их не отправляет.
Фильтры
Укажите request.findAttributes, чтобы Table начала работу с редактируемыми серверными фильтрами. Перед первым запросом объектов приложение копирует эти условия в состояние запроса панели в реестре ответов. Table читает это состояние и преобразует условия в формат API. Открывать окно фильтров и нажимать Apply для первого запроса не нужно. Исходную конфигурацию приложение не изменяет.
Начальный фильтр
Этот фрагмент Table задаёт условие isTemplate равно строке "true" для типа Operation. Проверьте, что сервер предоставляет Operation.isTemplate; если названия отличаются, укажите фактические тип и атрибут колонки.
json
{
"id": "templates",
"type": "table",
"request": {
"metaTypeName": "Operation",
"findAttributes": [
{ "field": "isTemplate", "compareType": "EQUAL", "value": "true" }
]
},
"filter": {
"fields": [{ "attribute": "isTemplate", "label": "Template" }]
},
"columns": [{ "attribute": "isTemplate", "label": "Template" }]
}После открытия Table её первое тело POST /Object/find содержит findAttributes: [{ "field": "isTemplate", "compareType": "EQUAL", "value": "true" }]. После ответа API таблица показывает строки, которые вернул сервер. Проверьте условие в первом запросе на вкладке Network инструментов браузера.
Каждый элемент request.findAttributes содержит field, compareType и value. field — непустая строка; value — строка или null.
compareType принимает EQUAL, NOT_EQUAL, CONTAIN, START_WITH, EMPTY, NOT_EMPTY. Для EMPTY и NOT_EMPTY не нужно значение сравнения: передайте null. Остальным операциям нужно значение для сопоставления. Передавайте "true", а не JSON true; числовые значения для сравнения тоже задавайте строками.
Поля Object, Link и вложенные пути
Для обычного запроса и запроса через linkedAttribute используйте field без префикса, например isTemplate или product|name. Приложение заменяет | на точки в редактируемом состоянии и возвращает | при отправке в API.
Запрос через Link содержит getSelectedObjectForEventId и linkName без metaTypeName. В нём obj:code относится к связанному Object, link:relationKind — к Link, а имя без префикса — к Object. Приложение сохраняет эти условия как obj и link в редактируемом состоянии и восстанавливает префиксы в теле API-запроса. Следующий фрагмент показывает структуру настройки. Замените OrderOperation, code и relationKind соответствующими именами вашего сервера. Панель-источник должна сохранять выбранный объект в событие order-selected действием addSelectedObjectToRequest:
json
{
"request": {
"getSelectedObjectForEventId": "order-selected",
"linkName": "OrderOperation",
"findAttributes": [
{ "field": "obj:code", "compareType": "START_WITH", "value": "OP-" },
{ "field": "link:relationKind", "compareType": "EQUAL", "value": "primary" }
]
},
"filter": {
"fields": [
{ "attribute": "code", "label": "Code" },
{ "attribute": "link.relationKind", "label": "Relation kind" }
]
}
}В API-запросе условие по Object содержит field: "obj:code", а условие по Link — field: "link:relationKind". Одно наличие события выбора не превращает поиск по атрибуту в запрос связанных объектов через Link.
Изменение, сброс и повторное открытие
filter.fields задаёт поля окна фильтров Table. Добавьте туда соответствующие поля, если пользователь должен редактировать начальные значения. Имена fields[].attribute отличаются от field в настройке запроса:
| Способ запроса | field в конфигурации | filter.fields[].attribute | field для API |
|---|---|---|---|
Обычный или через linkedAttribute | product|name | product.name | product|name |
| Через Link | obj:code или code | code | obj:code |
| Через Link | link:relationKind | link.relationKind | link:relationKind |
В полях окна используйте пути через точки, опускайте obj: и заменяйте link: на link.. В примере выше окно покажет OP- в поле Code и primary в поле Relation kind. Изменение поля с последующим Apply заменит существующее условие. Если скопировать имя с префиксом API в поле окна, оно будет обращаться к другому полю и не изменит начальное условие.
При открытии окно копирует текущие фильтры из реестра в свой черновик. Apply заменяет состояние реестра отправленными условиями, сбрасывает смещение страницы в 0, сохраняет размер страницы и запускает запрос Table.
Reset очищает только черновик окна: применённые фильтры не меняются, запрос не отправляется. Чтобы очистить применённые фильтры, нажмите Reset, затем Apply. Apply запишет [] в реестр и запустит новый запрос. Cancel или закрытие окна до Apply отменяет черновик и сохраняет применённые фильтры.
Сортировка, смена страницы, повторный запрос и повторное монтирование используют применённое состояние, включая [] после Reset и Apply, и не возвращают начальные условия из JSON. Приложение инициализирует их только при отсутствии findAttributes для панели в реестре. Это редактируемые значения по умолчанию, а не постоянные ограничения.
Если обычный поиск объектов Table, поиск через linkedAttribute или запрос через Link завершится ошибкой, Table уберёт прежние строки и снимет их выбор. Она покажет сообщение «Не удалось загрузить таблицу» и кнопку «Повторить»; заголовок и управление фильтрами останутся доступны. Нажмите «Повторить», чтобы запросить строки с текущими применёнными фильтрами, параметрами страниц и выбранным родителем. Пока идёт повторный запрос, вместо ошибки приложение покажет загрузку; после успешного ответа — строки или сообщение о пустом результате. Это поведение не описывает запросы через метод, запрос одного объекта или произвольный HTTP-запрос.
При запросе через linkedAttribute приложение отдельно добавляет обязательное условие равенства GUID выбранного родителя. Reset с последующим Apply его не удаляет. Произвольный HTTP-источник Table не использует фильтры объектов, исполнитель метода их не передаёт. Объявленное поле request.filter[] не участвует в фильтрации.
Сортировка
Каждое правило sortParams задаёт attribute, obj или link и направление. В состоянии панели возрастание записывается как "ASC", убывание — как историческое "Desc". Для API приложение преобразует их в "Asc" и "Desc".
json
{
"sortParams": [
{ "attribute": "priority", "sortDirection": "Desc" },
{ "attribute": "code", "sortDirection": "ASC" }
]
}Обычный запрос и запросы по выбранному объекту передают сортировку серверу. Для произвольного HTTP-ответа клиент сортирует полный массив и выделяет страницу. Сортируемая колонка добавляет управление в интерфейс, но не расширяет явно заданный request.attributeList.
Страницы
- Первое значение
pagination.rowsPerPageзадаёт начальный размер страницы Table. - Смена страницы или размера меняет
{ limit, offset }. - Apply нового фильтра сбрасывает
offsetв0и сохраняетlimit. - Обычный запрос, запрос через Link и запрос через атрибут передают эти параметры API.
- Произвольный HTTP-источник выделяет страницу из полного массива в клиенте.
- Без настройки страниц и ранее сохранённого состояния первый запрос объектов не содержит
pagination. Варианты размера страницы[3, 5, 10, 15]и резервное значение3в интерфейсе не задают ограничение серверу. УкажитеrowsPerPageявно, если первому запросу нужен определённый размер страницы.
Минимальная конфигурация
json
{
"id": "orders",
"type": "table",
"request": { "metaTypeName": "ProductionOrder" },
"columns": [{ "attribute": "name", "label": "Order" }]
}Полный пример главной и зависимой таблиц
Запрос зависимой таблицы требует выбора в главной. Сначала выберите заказ: его событие сохранит селектор, после чего условие покажет зависимую таблицу, а её запрос получит GUID выбранного заказа.
json
Открыть запрос через атрибут с выбором родителя и редактированием фильтров Открыть обычный запрос, запрос через Link и запрос одного объекта {
"id": "master-detail",
"type": "group",
"groupLayout": { "type": "rows" },
"panels": [
{
"id": "orders",
"type": "table",
"request": { "metaTypeName": "ProductionOrder" },
"events": [
{
"id": "order-selected",
"name": "onObjectSelect",
"actions": [{ "name": "addSelectedObjectToRequest" }]
}
],
"columns": [{ "attribute": "code", "label": "Order" }]
},
{
"id": "operations",
"type": "table",
"condition": {
"scenario": "objectSelected",
"eventId": "order-selected"
},
"request": {
"metaTypeName": "Operation",
"getSelectedObjectForEventId": "order-selected",
"linkedAttribute": "order"
},
"filter": {
"fields": [{ "attribute": "status", "label": "Status" }]
},
"pagination": { "rowsPerPage": [10, 25] },
"columns": [
{ "attribute": "code", "label": "Operation", "sortable": true },
{ "attribute": "status", "label": "Status" }
]
}
]
}Ограничения и расхождения
- Перед выбором способа запроса приложение не проверяет всю конфигурацию по схеме.
- Объявление события само по себе не задаёт выбранный объект; нужен выбор в панели-источнике.
- Общий механизм поддерживает методы, хотя старые локальные типы и описания Table перечисляют их не полностью.
- Локальный пример проверяет обработку ответа метода в Table. Метод и данные относятся к локальной демонстрации; наличие метода на рабочем сервере определяет его контракт.
request.filter[]объявлен в старой конфигурации Table, но не участвует в фильтрации.
Справочник параметров
Страницы параметров пока представлены на английском языке.
request.metaTypeNamerequest.attributeList[]request.getSelectedObjectForEventIdrequest.linkNamerequest.reverserequest.linkedAttributerequest.methodNamerequest.parentrequest.objects[]request.customRequest.methodrequest.customRequest.urlrequest.customRequest.idFieldrequest.customRequest.dataPathrequest.filter[]request.findAttributes[]request.findAttributes[].fieldrequest.findAttributes[].compareTyperequest.findAttributes[].valuerequest.sortParams[]request.sortParams[].attributerequest.sortParams[].objrequest.sortParams[].linkrequest.sortParams[].sortDirectionpagination.rowsPerPage[]