scripts:architecture

Архитектура

Скрипт представляет собой исполняемый JavaScript-код, который подписывается на события изменения полей формы и задает логику вычисления зависимых полей. Рассмотрим пример:

Есть форма с полями «Цена единицы товара», «Количество» и «Общая сумма». Поле «Общая сумма» можно заполнять автоматически (как произведение цены на количество) с помощью следующего кода:

form
  .onChange(['Цена единицы товара', 'Количество'])
  .setValue('Общая сумма', state => {
    const [price, quantity] = state.changes;

    if (!price || !quantity)
      return null;

    return price.value * quantity.value;
  });
Разберем подробнее этот код.

В контексте исполнения скрипта доступен глобальный объект form типа FormProxy, обеспечивающий взаимодействие кода скрипта с формой в Pyrus:

interface FormProxy {
  onChange(fieldNames: string[]): ChangeHandler;
  
  fetchSelfRegister(
    filterFn: (filter: RegisterFilter) => RegisterFilter,
    fieldNames: string[]
  ): Promise<RegisterResponse>;
}
Метод onChange принимает первым аргументом список названий полей формы (Цена единицы товара и Количество), при изменении которых нужно вычислить значения зависимых полей, и возвращает объект типа ChangeHandler.

Подсказка: метод onChange вызывается при изменении любого из полей, упомянутых в первом параметре. Результатом работы скрипта является заполнение зависимых полей или валидация. Но иногда этот процесс нарушается. Например, если значения исходных полей заполняются методами API, с помощью бота или клиентского приложения, которое не поддерживает скрипты, то в нужный момент скрипт не сработает и зависимые поля не заполнятся. В этом случае при настройке onChange следует указать дополнительный параметр TRUE. Благодаря ему скрипт будет запускаться не только при изменении указанных полей, но и каждый раз при входе в задачу (если параметр не указан как TRUE, то по умолчанию он считается FALSE). Настройка работает так: при первом входе пользователя в задачу после заполнения исходных полей через веб-браузер или другой клиент Pyrus с поддержкой скриптов, скрипт выполняется, то есть зависимые поля заполняются и/или валидация производится.

Подробнее про метод fetchSelfRegister см. Реестр формы.

ChangeHandler позволяет задать логику вычисления зависимых полей (Общая сумма), которая будет выполняться каждый раз при изменении любого из полей, перечисленных в методе onChange.

interface ChangeHandler {
  setValue(
    fieldName: string, 
    calcFunction: (state: FormState) => CompositeValue
  ): void;
  
  setValues(
    fieldNames: string[], 
    calcFunction: (state: FormState) => CompositeValue[]
  ): void;
  
  setValueAsync(
    fieldName: string, 
    calcFunction: (state: FormState) => Promise<CompositeValue>
  ): void;
  
  setValuesAsync(
    fieldNames: string[], 
    calcFunction: (state: FormState) => Promise<CompositeValue[]>
  ): void;  
  
  validate(
    fieldName: string, 
    validateFunction: (state: FormState) => {errorMessage: string} | null
  ): void;
  
  validateAsync(
    fieldName: string, 
    validateFunction: (state: FormState) => Promise<{errorMessage: string} | null>
  ): void;  
}

Аргументы метода setValue:

  • fieldName — название поля, значение которого нужно вычислить
  • calcFunction — функция вычисления значения поля.

Функция calcFunction получает на вход единственным аргументом объект типа FormState и возвращает новое значение (см. Формат значений полей) вычисленного поля, объявленного в методе setValue.

Для случаев, когда нужно вычислить сразу несколько полей на основе одних и тех же данных, удобно воспользоваться методом setValues — он принимает массив имен полей, а calcFunction в этом случае должна вернуть соответствующий массив значений этих полей.

Если для вычислений требуется произвести асинхронные операции (например, дождаться завершения запроса реестра), воспользуйтесь асинхронными версиями методов: setValueAsync и setValuesAsync. Их отличие в том, что в calcFunction возвращается Promise («обещание»), который вернет значения полей. Пример использования приведен в разделе Реестр формы.

Методы validate и validateAsync позволяют реализовать гибкую валидацию заполнения формы и отображение ошибок. Подробнее см. Валидация.

Объект FormState позволяет получить значения зависимых полей (Цена единицы товара и Количество), на основе которых вычисляется значение поля «Общая сумма»:

interface FormState {
  changes: FieldValue[];
  prev: FieldValue[];
}
Поле changes содержит массив текущих значений полей, перечисленных в методе onChange. Поле prev содержит массив «предыдущих» значений вычисляемых полей.

Была ли эта статья полезной?

Да, спасибо! Нет, остался вопрос