logo

Создание пользовательских представлений компонентов для типа данных

С помощью DevServer вы можете реализовать пользовательское представление типа данных. Для этого выполните следующие действия:

  1. Создайте модуль через DevServer.
  2. В модуле создайте компонент.
  3. В настройках компонента выберите тип данных, который будет реализовывать этот компонент.
  4. В контексте компонента создайте входную переменную такого же типа и с таким же типом связи, как в предыдущем шаге, и с обязательным именем Value.
  5. Реализовать форму для типа данных можно:
  • через конструктор форм;
  • через пользовательскую разметку.

Для управления и получения информации о типе данных реализованы дополнительные настройки:

Дополнительные настройки

/// <summary>
/// Только для чтения
/// </summary>
bool ReadOnly { get; }
 
/// <summary>
/// Модель валидации
/// </summary>
IValidationModel Validation { get; }
 
/// <summary>
/// Настройки типа данных
/// </summary>
TypeSettings Settings { get; }
 
/// <summary>
/// Настройки представления
/// </summary>
IClientAttributes Attributes { get; }
 
/// <summary>
/// Метаданные свойства
/// </summary>
IClientPropertyMetadata PropertyMetadata { get; }
 
/// <summary>
/// Событие нажатия клавиши
/// </summary>
/// <param name="ev">Модель события</param>
/// <returns></returns>
Task OnKeyPress(IKeyboardEvent ev);
 
/// <summary>
/// Событие потери фокуса
/// </summary>
/// <param name="ev">Модель события</param>
/// <returns></returns>
Task OnBlur(IChangeEvent ev);
 
/// <summary>
/// Событие установки фокуса
/// </summary>
/// <param name="ev">Модель события</param>
/// <returns></returns>
Task OnFocus(IFocusEvent ev);

IClientAttributes

/// <summary>
/// Настройки представления
/// </summary>
public interface IClientAttributes
{
    /// <summary>
    /// Название на форме
    /// </summary>
    string Name { get; }
 
    /// <summary>
    /// Описание на форме
    /// </summary>
    string Description { get; }
 
    /// <summary>
    /// Обязательно для заполнения
    /// </summary>
    bool Required { get; }
 
    /// <summary>
    /// Поле ввода блокировано
    /// </summary>
    bool Disabled { get; }
 
    /// <summary>
    /// Заполнитель
    /// </summary>
    string Placeholder { get; }
 
    /// <summary>
    /// Всплывающая подсказка
    /// </summary>
    string Tooltip { get; }
}

IClientPropertyMetadata

/// <summary>
/// Публичные метаданные свойства
/// </summary>
public interface IClientPropertyMetadata
{
    /// <summary>
    /// Уникальный идентификатор объекта
    /// </summary>
    Guid Uid { get; }
 
    /// <summary>
    /// Имя объекта
    /// </summary>
    string Name { get; }
 
    /// <summary>
    /// Отображаемое имя
    /// </summary>
    string DisplayName { get; }
 
    /// <summary>
    /// Описание
    /// </summary>
    string Description { get; }
 
    /// <summary>
    /// Uid типа свойства
    /// </summary>
    Guid TypeUid { get; }
 
    /// <summary>
    /// Uid подтипа свойства
    /// </summary>
    Guid SubTypeUid { get; }
 
    /// <summary>
    /// Обязательно для заполнения
    /// </summary>
    bool Required { get; }
 
    /// <summary>
    /// Может иметь пустое значение
    /// </summary>
    bool Nullable { get; }
}

Чтобы получить доступ к настройкам, в клиентском контроллере нужно обратиться к свойству Component.

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

Пример создания пользовательского представления типа «Адрес» в конструкторе форм

  1. Создайте компонент AddressCustomInput.
  2. В модуль добавьте ссылки на модули Работа с клиентами и ELMA.SDK.DTO.

3. В компоненте AddressCustomInput в качестве входного параметра создайте свойство с именем Value типа Адрес.

4. В настройках компонента на вкладке Дополнительно укажите тип, который реализует компонент — Адрес.

5. Сформируйте форму в конструкторе форм.

Поле Наименование отображается, если установлено значение Только для чтения. Поля адреса представлены, если задано значение На редактирование. Для этого у соответствующих колонок установлено значение Скрыть (одна для наименования, другая для всех остальных полей) со следующим кодом:

Код клиентского контроллера компонента
/// <summary>
/// Контроллер компонента "AddressCustomInput"
/// </summary>
partial class AddressCustomInput
{
    partial class ComponentController
    {
        /// <summary>
        /// Скрыть наименование
        /// </summary>
        /// <returns><c>true</c>, если необходимо скрыть наименование</returns>
        public bool HideName()
        {
            return !Component.ReadOnly;
        }
 
        /// <summary>
        /// Скрыть поля редактирования
        /// </summary>
        /// <returns><c>true</c>, если необходимо скрыть поля редактирования</returns>
        public bool HideEdit()
        {
            return Component.ReadOnly;
        }
    }
}

6. Сохраните компонент и опубликуйте модуль.

После публикации и импорта модуля в ELMA тип данных Адрес отобразится по-новому только во втором рантайме.

Для примера создадим страницу в разделе Интерфейсы. Добавим в неё свойство типа Юридическое лицо и вынесем на форму свойство типа Контрагент и свойство Юридический адрес типа Адрес из Контрагента.

В результате свойство типа Адрес сразу отображается по-новому.

Чтобы проверить работоспособность нового отображения типа данных, добавлена контекстная переменная Только на чтение.

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

На рисунке представлена форма для редактирования:

Таким образом отображается форма со значением Только на чтение:

Пример создания пользовательского представления типа «Да / Нет» при помощи пользовательской разметки

  1. Создайте компонент BooleanCustomInput.
  2. В модуль добавьте ссылки на модуль ELMA.SDK.DTO.
  3. В компоненте BooleanCustomInput добавьте входной параметр с именем Value типа Да / Нет.
  4. В настройках компонента на вкладке Дополнительно укажите тип, который реализует компонент, — Да / Нет.
  5. Сформируйте форму компонента при помощи кода. Для этого в разделе Сценарии на вкладке Отображение установите флажок Включить сценарий.
  6. Далее реализуйте пользовательскую разметку:
/// <summary>
/// Представление компонента "BooleanCustomInput"
/// </summary>
partial class BooleanCustomInput
{
    partial class Renderer
    {
        public override ReactElement Render()
        {
            return new Button(
                new Button.Props
                {
                    OnClick = ev => Dispatch.Invoke(c => c.Click()),
                    Style = Context.Value ? EleWise.ELMA.Core.React.UI.Views.ButtonStyle.Primary : EleWise.ELMA.Core.React.UI.Views.ButtonStyle.Danger,
                    Icon = Context.Value ? "check" : "cross"
                }
            );
        }
    }
}

Обратите внимание:

  1. В основе рендера всех компонентов второго рантайма ELMA лежит React с его правилами и особенностями.
  2. Если вам нужен свой очень сложный компонент (например, вы хотите изменить селектор сущности), придётся написать его полностью от начала и до конца.
  3. Методы Действия необходимо вызывать через Dispatch или DispatchAsync: в них доступны методы контроллера компонента.
  4. Ни в коем случае нельзя вызывать Dispatch или DispatchAsync в методе Render, поскольку это приведёт к ошибке. Dispatch или DispatchAsync вызываются исключительно в действиях: Click, Blur, ChangeEvent.
  5. В этом методе доступны все компоненты нашей библиотеки компонентов, а также DOM дерева.

Как показано в примере, в кнопке вызывается метод Click, который определён в клиентском контроллере:

/// <summary>
/// Контроллер компонента "BooleanCustomInput"
/// </summary>
partial class BooleanCustomInput
{
    partial class ComponentController
    {
        public void Click()
        {
            Component.OnBlur(new ChangeEvent<bool>
            {
                Value = !Context.Value
            });
        }
    }
}

Так как Value является входным параметром, изменять его напрямую нельзя, только через соответствующие действия.

Итак, тип Да / Нет отобразится в виде кнопки:

  • синяя кнопка с галочкой — если значение Да;
  • красная кнопка с крестиком— если значение Нет.

Сохраните компонент и опубликуйте модуль.
После публикации и импорта модуля в ELMA тип данных Да / Нет отобразится по-новому только во втором рантайме.
Для примера создадим страницу в разделе Интерфейсы. Добавим в неё свойство типа Да / Нет и вынесем его на форму.

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

Прикрепленные файлы