scripts:architecture

Архитектура

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

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

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

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

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

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

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

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

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