Skip to content

Получение коллекций через запросы ​

English version

Настройте request, чтобы панель запрашивала нужные объекты. Выбирайте способ по источнику данных: Table может показать объекты одного метатипа, связанные объекты, результат метода или произвольного HTTP-запроса. Зависимая панель может запросить один выбранный объект.

Это руководство описывает общий механизм запросов. Отдельный вариант панели может поддерживать более узкую конфигурацию или дополнять её поведение; перед переносом примера сверьтесь с руководством этого варианта.

Выбор способа запроса ​

ЗадачаОбязательные признакиКто обрабатывает запрос
Получить объекты одного метатипаmetaTypeNameСервер, поиск объектов
Получить объекты через LinkgetSelectedObjectForEventId + linkName без metaTypeNameСервер, связанные объекты
Найти объекты, ссылающиеся атрибутом на выбранный объектmetaTypeName + идентификатор события + linkedAttributeСервер, поиск по атрибуту
Получить один известный или выбранный объектПотребитель передаёт ObjectSelectorСервер
Использовать результат метаметодаmethodNameМетод формирует коллекцию
Показать произвольные JSON-строкиcustomRequestСервер возвращает массив; клиент сортирует и разбивает его на страницы

Для запроса по выбранному объекту пользователь сначала выбирает строку в панели-источнике. Её обработчик события должен выполнить addSelectedObjectToRequest: приложение сохраняет селектор выбранного объекта для события, а зависимый запрос читает его по идентификатору события. Одного объявления события без выбора строки недостаточно.

Порядок выбора ​

Общий механизм выбирает первое совпадение:

  1. customRequest.
  2. methodName.
  3. Один objectSelector, переданный потребителем.
  4. metaTypeName + событие выбора + linkedAttribute.
  5. Событие выбора + linkName без metaTypeName.
  6. metaTypeName.

Оставляйте один набор признаков. Это порядок совместимости: случайно оставленный customRequest получит приоритет над metaTypeName, а метод — над признаками обычного запроса или запроса связанных объектов.

Состав ответа и пути атрибутов ​

Для обычного запроса и запроса через Link приложение выбирает список атрибутов:

  1. Явный список, переданный вызывающим потребителем.
  2. request.attributeList.
  3. Атрибуты непосредственных колонок панели.

Приложение удаляет повторы и заменяет точки вложенных путей на | для 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 берёт общее количество, размер и смещение для отображения страниц.

Запросы по выбранному объекту ​

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. Имя и данные относятся к демонстрации; они не подтверждают наличие такого метода на рабочем сервере.

Открыть вкладку Method request с получением строк через MetaMethods/Run

Произвольный 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 позволяют проверить обработку массива в клиенте. Не добавляйте в этот пример заголовки или тело: текущий исполнитель их не отправляет.

Открыть вкладку Custom request: извлечение массива, типы колонок, сортировка и страницы

Фильтры ​

Укажите 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; числовые значения для сравнения тоже задавайте строками.

Для обычного запроса и запроса через 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[].attributefield для API
Обычный или через linkedAttributeproduct|nameproduct.nameproduct|name
Через Linkobj:code или codecodeobj:code
Через Linklink:relationKindlink.relationKindlink: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
{
  "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" }
      ]
    }
  ]
}
Открыть запрос через атрибут с выбором родителя и редактированием фильтров Открыть обычный запрос, запрос через Link и запрос одного объекта

Ограничения и расхождения ​

  • Перед выбором способа запроса приложение не проверяет всю конфигурацию по схеме.
  • Объявление события само по себе не задаёт выбранный объект; нужен выбор в панели-источнике.
  • Общий механизм поддерживает методы, хотя старые локальные типы и описания Table перечисляют их не полностью.
  • Локальный пример проверяет обработку ответа метода в Table. Метод и данные относятся к локальной демонстрации; наличие метода на рабочем сервере определяет его контракт.
  • request.filter[] объявлен в старой конфигурации Table, но не участвует в фильтрации.

Справочник параметров ​

Страницы параметров пока представлены на английском языке.

Следующие шаги ​