Работа элемента управления с данными карточки

Чтобы элемент управления мог работать с данными карточки, его необходимо определённым образом подготовить:

  1. Добавьте в описатель элемента управления свойства: DataSource, DataField и Binding.

    Первые два свойства предоставляют возможность выбрать в настройках элемента управления секцию (DataSource) и поле карточки (DataField) с данными. Свойство биндинг (Binding) — не отображаемое в настройках свойство, с которым значение элемента управления передается в его клиентский компонент.

    Элемент управления также может получать данные из карточки, связанной с текущей. Для возможности выбора типа источника (текущая карточки или определённый дополнительный источник) в описатель также нужно добавить свойство ExtendedDataSource.

    Текстовый описатель:
    …
        <Properties>
           …
           <Property Type="DataSource" />
           <Property Type="DataField" />
           <Property Type="Binding" />
           <Property Type="ExtendedDataSource" /> (1)
         </Properties>
    1 Не обязательно.
    Бинарный описатель:
    …
        PropertyDescriptions =
        {
            …
            PropertyFactory.GetDataSourceProperty(),
            PropertyFactory.GetDataFieldProperty(),
            PropertyFactory.GetBindingProperty(),
            PropertyFactory.GetExtendedDataSourceProperty(),
        }
  2. Добавить в клиентский компонент элемента управления в класс параметров поле для хранения значения элемента управления. Тип поля должен соответствовать типу значения элемента управления.

    export class SomeControlParams extends BaseControlParams {
         @rw value?: string;
    }
  3. Добавить в клиентский компонент элемента управления в интерфейс состояния поле для хранения биндинга. Тип поля должен быть IBindingResult<string>. Тип string нужно заменить на тип значения элемента управления.

    export interface SomeControlState extends SomeControlParams, BaseControlState {
         binding: IBindingResult<string>(1)
    }
    1 Если элемент управления предназначен только для чтения значения (изменять не требуется), свойство binding не требуется.
  4. Добавить в клиентский компонент элемента управления в интерфейсный класс set-метод, загружающий значение элемента управления. Метод должен быть помечен декоратором @handler("binding").

    @handler("binding")
    private set binding(binding: IBindingResult<string>) {
        this.state.value =  binding && binding.value;
        this.state.binding = binding;
    }
  5. Добавить в клиентский компонент элемента управления в интерфейсный класс метод, возвращающий биндинги.

    "Биндинг" формируется методом getBindingResult, в который нужно передать:

    • Текущий "биндинг" (из свойства класса, в которое "биндинг" был сохранен при получении с сервера.

    • Текущее значение элемента управления.

    • Поле, в котором содержится ассоциированное с ЭУ название элемента карточки.

    Переданное значение будет записано в историю изменений карточки: Выполнилась операция "Редактирование". Значение поля {Значение аргумента} было изменено с …​ на …​.

    protected getBindings() {
        return [getBindingResult(this.state.binding, this.params.value, () => at(SomeControlParams).controlTitle)];
    }

    Метод getBindings должен вернуть IBindingResult, для получения которого вызывается метод getBindingResult, принимающий:

    • Биндинг, полученный при загрузке элемента управления.

    • Новое значение элемента управления (в примере, оно хранится в поле this.params.value).

    • Поле, в котором содержится ассоциированное с элементом управления название элемента карточки. Данное значение используется при формировании истории изменений карточки: Выполнилась операция "Редактирование". Значение поля {Значение аргумента} было изменено с …​ на …​.

  6. В класс реализации добавить функцию, сохраняющую значение элемента управления в поле value.

    changedHandler = (event) => {
        this.state.value = event.target.value;
        this.forceUpdate();
    }

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

    Чтобы использовать операцию редактирования, необходимо:
    • Добавить в описатель элемента управления свойство EditOperation:

      <Properties>
              (1)
              <Property Type="DataSource" />
              <Property Type="DataField" />
              <Property Type="Binding" />
      
              <Property Type="EditOperation" /> (2)
      </Properties>
      1 Свойства, перечисленные ранее, также должны быть указаны.
      2 Добавляем операцию редактирования.
    • Добавить код проверки операции редактирования в функцию загрузки значения элемента управления (binding):

      @handler("binding")
      protected set binding(binding: IBindingResult<boolean>) {
          this.state.canEdit = !binding || editOperations.available(binding.editOperation);
      }

Проверка прав пользователя на изменение значения

Возможность изменения значения ЭУ (или выполнения других операций) проверяется по доступности пользователю операции редактирования.

Чтобы добавить возможность настраивать для ЭУ операцию редактирования, нужно добавить в описатель элемента управления свойство EditOperation.

<?xml version="1.0" encoding="utf-8" ?>
<Controls>
    <Control Name="Somecontrol" DisplayName="Somecontrol">
        <Properties>
            <Property Type="Name" />

            <Property Type="DataSource" /> (1)
            <Property Type="DataField" />
            <Property Type="Binding" />
            <Property Type="EditOperation" /> (2)
        </Properties>
    </Control>
</Controls>
1 Свойства, используемые для связывания ЭУ с данными карточки.
2 Свойство Операция редактирования.

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

Чтобы добавить проверку операции редактирования в представительную часть ЭУ, нужно:
  1. Добавить в "интерфейс состояния" поле, в которое будет сохраняться результат проверки.

  2. В "интерфейсном классе" в методе, отвечающем за загрузку биндинга, организовать проверку операции редактирования:

    @handler("binding")
    protected set binding(binding: IBindingResult<boolean>) {
        this.state.canEdit = !binding || this.props.services.editOperations.available(binding.editOperation) (1)
    }
    1 Сохраняем результат проверки доступности операции в поле canEdit.
В приведенном коде проверка доступности операции осуществляется с помощью клиентского сервиса $EditOperationStore. Подробности в пункте Получение сервисов в клиентском компоненте.