Создание пользовательских представлений компонентов для типа данных
С помощью DevServer вы можете реализовать пользовательское представление типа данных. Для этого выполните следующие действия:
- Создайте модуль через DevServer.
- В модуле создайте компонент.
- В настройках компонента выберите тип данных, который будет реализовывать этот компонент.
- В контексте компонента создайте входную переменную такого же типа и с таким же типом связи, как в предыдущем шаге, и с обязательным именем Value.
- Реализовать форму для типа данных можно:
- через конструктор форм;
- через пользовательскую разметку.
Для управления и получения информации о типе данных реализованы дополнительные настройки:
Дополнительные настройки
/// <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 создан тестовый модуль с примерами, который вы можете скачать, нажав на название прикреплённого файла в конце статьи.
Пример создания пользовательского представления типа «Адрес» в конструкторе форм
- Создайте компонент AddressCustomInput.
- В модуль добавьте ссылки на модули Работа с клиентами и 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 тип данных Адрес отобразится по-новому только во втором рантайме.
Для примера создадим страницу в разделе Интерфейсы. Добавим в неё свойство типа Юридическое лицо и вынесем на форму свойство типа Контрагент и свойство Юридический адрес типа Адрес из Контрагента.
В результате свойство типа Адрес сразу отображается по-новому.
Чтобы проверить работоспособность нового отображения типа данных, добавлена контекстная переменная Только на чтение.
Опубликуем страницу и проверим, что получилось.
На рисунке представлена форма для редактирования:
Таким образом отображается форма со значением Только на чтение:
Пример создания пользовательского представления типа «Да / Нет» при помощи пользовательской разметки
- Создайте компонент BooleanCustomInput.
- В модуль добавьте ссылки на модуль ELMA.SDK.DTO.
- В компоненте BooleanCustomInput добавьте входной параметр с именем Value типа Да / Нет.
- В настройках компонента на вкладке Дополнительно укажите тип, который реализует компонент, — Да / Нет.
- Сформируйте форму компонента при помощи кода. Для этого в разделе Сценарии на вкладке Отображение установите флажок Включить сценарий.
- Далее реализуйте пользовательскую разметку:
/// <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"
}
);
}
}
}
Обратите внимание:
- В основе рендера всех компонентов второго рантайма ELMA лежит React с его правилами и особенностями.
- Если вам нужен свой очень сложный компонент (например, вы хотите изменить селектор сущности), придётся написать его полностью от начала и до конца.
- Методы Действия необходимо вызывать через Dispatch или DispatchAsync: в них доступны методы контроллера компонента.
- Ни в коем случае нельзя вызывать Dispatch или DispatchAsync в методе Render, поскольку это приведёт к ошибке. Dispatch или DispatchAsync вызываются исключительно в действиях: Click, Blur, ChangeEvent.
- В этом методе доступны все компоненты нашей библиотеки компонентов, а также DOM дерева.
Как показано в примере, в кнопке вызывается метод Click, который определён в клиентском контроллере:
/// <summary>
/// Контроллер компонента "BooleanCustomInput"
/// </summary>
partial class BooleanCustomInput
{
partial class ComponentController
{
public void Click()
{
Component.OnBlur(new ChangeEvent<bool>
{
Value = !Context.Value
});
}
}
}
Так как Value является входным параметром, изменять его напрямую нельзя, только через соответствующие действия.
Итак, тип Да / Нет отобразится в виде кнопки:
- синяя кнопка с галочкой — если значение Да;
- красная кнопка с крестиком— если значение Нет.
Сохраните компонент и опубликуйте модуль.
После публикации и импорта модуля в ELMA тип данных Да / Нет отобразится по-новому только во втором рантайме.
Для примера создадим страницу в разделе Интерфейсы. Добавим в неё свойство типа Да / Нет и вынесем его на форму.
После публикации страницы проверьте работоспособность.