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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Чтобы добавить возможность настраивать для ЭУ операцию редактирования, нужно добавить в описатель элемента управления свойство 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>
xml
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)
    }
    typescript
    1 Сохраняем результат проверки доступности операции в поле canEdit.
В приведенном коде проверка доступности операции осуществляется с помощью клиентского сервиса $EditOperationStore. Подробности в пункте Получение сервисов в клиентском компоненте.