Операции выборки#

Выборка взаимодействует с программным окружением системы с помощью операций. Операция выборки обрабатывает событие, вызванное пользователем, системой или прикладным процессом.

Операции могут выполняться автоматически при возникновении служебных событий или запускаться в результате явного действия пользователя.

Операции используются для работы с данными выборки, обработки событий формы, изменения значений атрибутов, управления фильтрами и выполнения пользовательской бизнес-логики.

Виды операций#

В выборках используются следующие виды операций:

  • базовые операции;

  • служебные операции;

  • системные операции;

  • сеттеры атрибутов;

  • операции фильтров;

  • пользовательские операции.

Базовые операции предназначены для работы с набором данных. Они отвечают за добавление, удаление и обновление записей, получение данных и навигацию по датасету.

Базовые операции обычно определяются в выборках-предках. Часть таких операций выполняется автоматически при определённых действиях пользователя. Например, beforeEdit вызывается перед началом редактирования, afterEdit — после его завершения, а checkWorkAbility — при переходе между записями.

Служебные операции выполняют вспомогательные действия, связанные с работой формы и её выборок.

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

Сеттеры изменяют значения атрибутов выборки. При вводе значения в поле формы вызывается связанная с ним операция-сеттер. По умолчанию сеттер вызывает серверный метод изменения значения соответствующего атрибута класса.

Сеттеры для атрибутов класса создаются автоматически.

Операции фильтров обеспечивают применение, очистку и сброс условий фильтрации.

Пользовательские операции создаются разработчиком и могут выполнять серверную или клиентскую логику. Например, пользовательская операция может изменить данные, открыть другую форму или вывести сообщение.

Асинхронный вызов операций#

Метод asyncExec планирует асинхронное выполнение операции выборки. Команда на выполнение операции добавляется в конец очереди команд рабочего сеанса.

Операция выполняется в потоке рабочего сеанса после завершения текущего события или операции и перехода выборки в состояние idle.

Метод можно вызывать без аргументов или передавать аргументы вызываемой операции.

Пример вызова операции без аргументов:

selection.opers().asyncExec(
  operationName = "MyOperation"
)

Параметр operationName содержит системное имя вызываемой операции.

Пример вызова операции с аргументами:

val operArguments: Array[Any] =
  Array("arg1", "arg2")

selection.opers().asyncExec(
  "MyOperation",
  args = operArguments
)

Параметр args содержит аргументы, передаваемые операции.

Метод доступен только в рабочем сеансе с очередью команд. Такая очередь используется в сеансах с графическим интерфейсом.

В REST-, SOAP- и Report-сеансах очередь команд отсутствует.

Примечание

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

Если метод asyncExec(String operationName, Object[] args) вызывается из потока рабочего сеанса, но операция с указанным именем отсутствует, возникает исключение ApplicationException.

Выполнение нескольких операций#

Несколько операций, последовательно добавленных через asyncExec, выполняются в порядке поступления команд в очередь рабочего сеанса.

selection.opers().asyncExec(
  operationName = "FirstOperation"
)

selection.opers().asyncExec(
  operationName = "SecondOperation"
)

selection.opers().asyncExec(
  operationName = "ThirdOperation"
)

Асинхронное обновление дочерней выборки#

В следующем примере мастер-выборка содержит список файлов, а дочерняя выборка отображает содержимое выбранного файла.

После актуализации документа для дочерней выборки планируется выполнение операции refresh.

def updateCurrentDoc(): Unit = {
  // Получить глобальный идентификатор текущего документа
  val gidvDocCur =
    selection.getVar("gid").asNGid

  // Актуализировать документ
  thisApi().updateDoc(gidvDocCur)

  // Найти дочернюю выборку с просмотром документа
  val sel =
    selection.form.findSelection(
      Tst_FileViewerAvi.card_Viewer()
    )

  // Асинхронно обновить активную выборку
  if (sel != null && sel.isActive) {
    sel.opers().asyncExec("refresh")
  }
}

Метод findSelection() ищет дочернюю выборку на форме. Перед вызовом операции проверяется, что выборка найдена и активна.

Вызов sel.opers().asyncExec("refresh") планирует выполнение операции refresh в найденной выборке.

Базовые операции#

Для автоматического выполнения базовой или служебной операции используется её предопределённое системное имя.

В выборках используются следующие базовые операции:

  • onRefresh — загружает данные в датасет. При повторном вызове обновляет весь набор данных;

  • onRefreshItem — обновляет текущую запись;

  • onRefreshExt — выполняет дополнительный запрос к базе данных для получения полей-заголовков ссылочных объектов;

  • beforeEdit — выполняется перед началом редактирования записи;

  • afterEdit — выполняет финальную проверку введённых данных;

  • insert — добавляет новую запись;

  • delete — удаляет запись;

  • checkWorkAbility — проверяет состояние операций и доступность редактирования атрибутов;

  • onLoadMeta — выполняется при загрузке метаданных;

  • onUnloadMeta — выполняется при выгрузке метаданных;

  • beforeOpen — выполняется перед открытием выборки;

  • afterOpen — выполняется после открытия выборки;

  • onShow — выполняется после формирования интерфейса формы;

  • onControllerCreated — выполняется после создания фрейма отображения выборки.

onRefreshExt#

Операция onRefreshExt используется только для объектных запросов в onRefresh и onRefreshItem.

Атрибуты класса, используемые в запросе, необходимо передать в блоке with.

Для атрибутов с типом, отличным от Long, необходимо явно указать тип в аннотации /*@...*/.

Для строковых атрибутов используются типы:

  • "String";

  • "NString";

  • "varchar".

Пример аннотации строкового атрибута:

/*@NString*/

Для числовых атрибутов используется тип "Number":

/*@Number*/

Если тип не указан, система попытается преобразовать значение атрибута к типу bigint.

beforeEdit и afterEdit#

Операция beforeEdit выполняется при начале изменения объекта. Она используется для подготовительных действий перед редактированием записи.

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

checkWorkAbility#

Операция checkWorkAbility проверяет:

  • состояние операций выборки;

  • доступность операций для пользователя;

  • возможность редактирования атрибутов.

Операция вызывается:

  • при открытии выборки;

  • при переходе между записями;

  • после выполнения операции, для которой включён соответствующий признак вызова checkWorkAbility.

Операции загрузки и отображения#

Операция onLoadMeta выполняется при загрузке метаданных.

Метаданные загружаются один раз при первом открытии экземпляра выборки на фрейме. Поэтому onLoadMeta также выполняется один раз.

Операция onUnloadMeta выполняется при выгрузке метаданных.

Операция beforeOpen вызывается перед открытием выборки. Её можно использовать для создания дополнительных параметров, необходимых выборке.

Операция afterOpen вызывается сразу после открытия выборки. Например, в ней можно переопределить наименования колонок.

Операция onShow выполняется после создания и отображения элементов формы.

Операция onControllerCreated выполняется после создания фрейма отображения выборки. Она также вызывается для элементов формы, которые не отображались при первоначальном открытии формы. Например, операция будет вызвана для выборки на закладке после первого открытия этой закладки.

Служебные операции#

В выборках используются следующие служебные операции:

  • saveForm — сохраняет данные формы;

  • cancelForm — отменяет изменения на форме;

  • closeFormOk — закрывает форму с подтверждением выбора;

  • closeFormCancel — закрывает форму по операции Выход или по кнопке закрытия окна;

  • beforeCloseForm — выполняется перед закрытием формы;

  • afterCloseForm — выполняется после закрытия формы;

  • onCloseFormQuery — выполняется в начале закрытия формы и позволяет отменить закрытие.

Предопределённые операции#

В выборках доступны следующие предопределённые операции:

  • applyUniFilter — применяет настроенные условия фильтрации и повторно запрашивает данные;

  • resetUniFilter — отменяет наложенные на выборку фильтры;

  • clearUniFilter — очищает условия фильтрации;

  • showAuditObject — открывает окно аудита действий с фильтром по текущему объекту;

  • showAboutObject — открывает окно с системной информацией об объекте;

  • copyObject — копирует объект;

  • cardEdit — открывает объект в карточке с предварительным выбором выборки и отображения;

  • allowEdit — разрешает или запрещает редактирование объектов в списке;

  • showTab — открывает или закрывает детальную часть.

Операция allowEdit по умолчанию доступна для редактируемых списков.

Сеттеры атрибутов#

Сеттер — операция, которая устанавливает значение атрибута текущей записи с учётом его типа.

Системное имя сеттера формируется из:

  • префикса set;

  • имени атрибута.

Общий формат имени:

set<attributeName>

Например, для атрибута sCaption используется сеттер:

setsCaption

Обработчики операций и событий#

Обработчики позволяют вынести общую логику, выполняемую после операций, сеттеров или событий выборки, в универсальный метод с единой точкой входа. Например, в методе-обработчике можно:

  • пересчитывать зависимые значения после изменения атрибутов;

  • обновлять состояние выборки после выполнения операции.

При добавлении нового атрибута не требуется вручную прописывать вызов постобработки в его сеттере.

Метод handlers.addAfterEvent регистрирует метод-обработчик, который вызывается после заданной операции, сеттера или события. Для регистрации указываются:

  • значение RepEvent, определяющее отдельное событие или группу обрабатываемых вызовов;

  • метод-обработчик, содержащий логику постобработки, например execAfterSetter.

В следующем примере метод execAfterSetter принимает в параметре setterName имя выполненного сеттера:

def execAfterSetter(setterName: String): Unit = {
  // Логика постобработки
}

Метод-обработчик регистрируется при загрузке метаданных отображения выборки в методе onLoadMeta:

override protected def onLoadMeta(): Unit = {
  super.onLoadMeta()

  selection.baseRep
    .unwrap(classOf[InternalRep])
    .handlers
    .addAfterEvent(
      RepEvent.allSetters,
      execAfterSetter
    )
}

После регистрации execAfterSetter вызывается после выполнения каждого сеттера отображения выборки. Обработчик охватывает сеттеры базовых атрибутов, JSON-хранимых атрибутов и универсальных характеристик независимо от имени и типа атрибута.

При добавлении нового атрибута или сеттера отдельно добавлять вызов метода-обработчика не требуется.

Для обработки групп вызовов в RepEvent предусмотрены следующие значения:

  • allEvents — все события;

  • allOperations — все операции, кроме сеттеров и событий;

  • allSetters — все сеттеры;

  • all — все операции, сеттеры и события.

Обработчик также можно зарегистрировать для отдельного события:

  • onRefresh;

  • onRefreshItem;

  • beforeRefresh;

  • afterRefresh;

  • checkWorkability;

  • beforeScroll;

  • afterScroll;

  • onShow;

  • onUnloadMeta;

  • afterCloseForm;

  • afterEdit.

Специальные операции контролов#

Специальные операции контролов обрабатывают изменение фокуса ввода:

  • onFocusedFieldChanged — выполняется после перехода между колонками списка или дерева, а также между контролами карточки или панели фильтров;

  • onFocusedCellChanged — выполняется после перехода между ячейками списка;

  • onFrameActivated — выполняется при переходе фокуса в список, дерево или карточку.

Отображение операций#

Операция может отображаться:

  • на панели инструментов фрейма;

  • в контекстном меню;

  • в главном меню;

  • на панели быстрого запуска под главным меню.

Отображение операции в главном меню и на панели быстрого запуска доступно только для выборок приложений главного меню.

Способ размещения операции определяется её свойствами.

Пользовательские JEXL-операции#

Пользовательские JEXL-операции позволяют добавлять операции в существующие выборки без изменения прикладного кода.

Для таких операций поддерживаются:

  • создание;

  • удаление;

  • переименование;

  • настройка поведения;

  • настройка отображения.

Операции, заданные в отображении Default, доступны в остальных отображениях выборки. Свойства операции можно переопределить для отдельного отображения.

Примечание

Системные имена пользовательских JEXL-операций начинаются с префикса jexl_.

Свойства JEXL-операции#

Свойство

Описание

Наименование

Наименование операции, отображаемое в интерфейсе и при наведении указателя

Описание

Пояснение назначения операции

Порядковый номер

Определяет положение операции. Чем меньше значение, тем выше операция при вертикальном размещении или левее при горизонтальном

Иконка

Номер изображения, используемого для операции

Активность

Если выключена, операция не отображается в интерфейсе и недоступна при вызове из кода

Видимость

Если выключена, операция не отображается в интерфейсе, но остаётся доступной при вызове из кода

Доступность для взаимодействия

Если выключена, операция отображается неактивной и недоступна для выполнения. Для применения свойства должны быть включены Активность и Видимость

Флаг (checked)

Определяет, является ли операция переключателем с устанавливаемым или снимаемым флагом

Вызвать checkWorkability

После выполнения операции вызывает checkWorkAbility

Обновить запись после выполнения

Обновляет текущую запись после выполнения операции

Обновить запись перед выполнением

Обновляет текущую запись перед выполнением операции

Видимость операции на всех панелях

Отображает операцию на всех основных панелях интерфейса

Видимость в главном меню

Отображает операцию в верхней панели интерфейса

Видимость на панели быстрого запуска

Отображает операцию на панели быстрого запуска

Видимость в контекстном меню

Отображает операцию в контекстном меню

Видимость на панели управления

Отображает операцию на панели управления объектом

Тип привилегий для доступа

Определяет объектную привилегию, необходимую для просмотра и выполнения операции

Комбинация горячих клавиш

Определяет сочетание клавиш для выполнения операции

Коллекция изображений

Определяет коллекцию, из которой выбирается иконка

Группа на панели быстрого доступа

Определяет группу операции на панели быстрого запуска

Операция-предок

Определяет положение операции в дереве меню

Если в свойстве Операция-предок указано значение Сущности, операция отображается внутри раздела Сущности вместе с другими операциями этого раздела.

Хранение JEXL-операций#

Свойства пользовательских операций хранятся в таблице Btk_SelOperOverride.

Каждое свойство операции хранится в отдельной записи.

JEXL-скрипт и клонирующий SQL-запрос хранятся в поле sJexlOperScript. Поле sValue, используемое для остальных свойств, ограничено длиной 255 символов.

В таблице используются поля:

  • sPropName — имя свойства операции;

  • sJexlOperScript — JEXL-скрипт операции или клонирующий SQL-запрос. Поле используется для свойств с sPropName, равным sJexl или cloneQuery;

  • sValue — значение свойства операции;

  • sOperName — системное имя операции;

  • sMasterSel — системное имя выборки;

  • sMasterRep — имя отображения выборки.

Пользовательская операция считается заданной для выборки и отображения, если существует запись со следующими значениями:

  • sMasterSel соответствует системному имени выборки;

  • sMasterRep соответствует имени отображения или значению Default;

  • sPropName имеет значение sJexl.

Чтобы операция отображалась в интерфейсе, для неё необходимо указать:

  • наименование;

  • порядковый номер;

  • иконку.

Иконку можно не указывать для операций главного и контекстного меню.

Иконки операций#

Иконки операций можно подключать:

  1. Из ресурсов сервера.

  2. Из базы данных.

  3. По URL.

Иконки из ресурсов сервера#

Коллекции изображений находятся в каталоге:

[G3_HOME]/resources/imagecollection

Каждый подкаталог является отдельной коллекцией изображений. Вложенные файлы являются элементами коллекции, а их номера соответствуют именам файлов.

Это основной способ подключения иконок.

Иконки из базы данных#

Коллекции изображений загружаются из таблицы btk_component.

Данные коллекции хранятся в поле clobdataxml.

Подключение иконки по URL#

Для подключения отдельной иконки указывается её URL.

Иконки из Java-ресурсов модуля#

Файлы изображений можно размещать в ресурсных каталогах соответствующего модуля.

Например, коллекции изображений модуля BTK находятся в каталоге:

ru/bitec/app/btk/images

Каждой коллекции соответствует отдельный каталог.

Для коллекции toolbar используется следующая структура:

  • ru/bitec/app/btk/images/toolbar — изображения с минимальным разрешением 16 × 16 точек;

  • ru/bitec/app/btk/images/toolbar/24x24 — изображения с разрешением 24 × 24 точки;

  • ru/bitec/app/btk/images/toolbar/disabled — обесцвеченные копии изображений коллекции toolbar, используемые для неактивных операций на панелях управления.

При необходимости можно создавать каталоги изображений с большим разрешением.

Для указания изображения операции из Java-ресурсов используется свойство imageUri аннотации @Oper.

Пример:

@Oper(
  caption = "Род",
  headOperation = "references",
  imageUri = "ru/bitec/app/gs3/images/toolbar/61.png"
)
def open_Bs_Kind_RoList(): Unit = {
  Bs_KindAvi.roList().newForm().open()
}

Если одновременно указаны свойства imageIndex и imageUri, используется значение imageUri.