Вычисляемые свойства экземпляров компонентов

Свойства экземпляров компонентов интерфейса могут быть заданы не конкретным значением, а некоторой функцией. Иными словами, они могут быть вычисляемыми. Прямым аналогом этого являются формулы ячеек в Excel.

Например, в форме расположены поле ввода и флажок:

Вы можете указать, что видимость поля ввода будет зависеть от состояния флажка — установлен он или нет:

ВидЭлемента: КомпонентИнтерфейса
Ид: 29354d98-2467-4f72-a2b0-985e28106372
Имя: ФормаПолеВводаФлажок
Наследует:
    Тип: Форма
    ВключатьВАвтоИнтерфейс: Ложь
    Содержимое:
        Тип: ОбычнаяГруппа
        Ориентация: Горизонтальная
        Содержимое:
            -
                Тип: Флажок
                Имя: МойФлажок
            -
                Тип: ПолеВвода<Строка>
                Имя: МоеПолеВвода
                Видимость: =Компоненты.МойФлажок.Значение

Важным моментом здесь является то, что свойства компонентов не только вычисляемые, но и наблюдаемые. То есть при их изменении (МойФлажок.Значение) автоматически выполняется пересчет зависящих от них вычисляемых свойств (МоеПолеВвода.Видимость).

отслеживает изменение свойств компонентов и автоматически выполняет зависящую от них системную логику, например:

  • обновление интерфейса, если свойство влияет на внешний вид компонента;
  • обновление данных, если свойство влияет на их выборку;
  • обновление отображаемых в компоненте данных при изменении свойства, ссылающегося на эти данные.
В результате пример будет работать следующим образом:
  • если флажок сброшен, то виден только он;
  • если флажок установлен, то виден он и поле ввода.

Методы значений

Как вы, наверное, заметили, Компоненты.МойФлажок.Значение — это конструкция встроенного языка, которая обращается к экземпляру типа ФормаПолеВводаФлажок.Компоненты (подробнее) и получает от него именованный компонент содержимого МойФлажок и, далее, значение этого флажка типа Булево.

Это говорит о том, что при описании свойств компонентов вы можете использовать и другие возможности встроенного языка, например, методы значений.

В этом примере значение флажка регулирует доступность поля ввода, а в само поле ввода записывается представление значения флажка:

ВидЭлемента: КомпонентИнтерфейса
Ид: 29354d98-2467-4f72-a2b0-985e28106372
Имя: ФормаПолеВводаФлажок
Наследует:
    Тип: Форма
    ВключатьВАвтоИнтерфейс: Ложь
    Содержимое:
        Тип: ОбычнаяГруппа
        Ориентация: Горизонтальная
        Содержимое:
            -
                Тип: Флажок
                Имя: МойФлажок
            -
                Тип: ПолеВвода<Строка>
                Имя: МоеПолеВвода
                Доступность: =Компоненты.МойФлажок.Значение
                Значение: =Компоненты.МойФлажок.Значение.Представление()

Пример работает следующим образом:

Методы модулей

Если для вычисления значения свойства компонента вам требуется более сложный алгоритм, вы можете разместить его в одном из модулей. Например, в модуле самого компонента интерфейса, в данном случае — в модуле формы ФормаПолеВводаФлажок:

метод ЗначениеДляПоля(Флажок: Булево): Строка
    выбор Флажок
    когда Истина
        возврат "Поле доступно"
    иначе
        возврат "Поле недоступно"
    ;
;

А в свойстве компонента просто обратиться к этому методу:

ВидЭлемента: КомпонентИнтерфейса
Ид: 29354d98-2467-4f72-a2b0-985e28106372
Имя: ФормаПолеВводаФлажок
Наследует:
    Тип: Форма
    ВключатьВАвтоИнтерфейс: Ложь
    Содержимое:
        Тип: ОбычнаяГруппа
        Ориентация: Горизонтальная
        Содержимое:
            -
                Тип: Флажок
                Имя: МойФлажок
            -
                Тип: ПолеВвода<Строка>
                Имя: МоеПолеВвода
                Доступность: =Компоненты.МойФлажок.Значение
                Значение: =ЗначениеДляПоля(Компоненты.МойФлажок.Значение)

Пример работает следующим образом:

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

Единственное, о чем нужно позаботиться, — это о том, чтобы метод был виден снаружи модуля. Например, с помощью аннотации @ВПодсистеме (подробнее):

@ВПодсистеме
метод СвоеЗначениеСтрокой(): Строка

    выбор Значение
    когда Истина
        возврат "Поле доступно"
    иначе
        возврат "Поле недоступно"
    ;
;

Вычисляемые свойства колонок таблиц

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

Например, источником таблицы может являться динамический список и тогда ДанныеСтроки будут иметь тип СтрокаДинамическогоСписка. Эти данные вы можете использовать для того, чтобы выбрать подходящее оформление для колонки Возраст, например:

ВидЭлемента: КомпонентИнтерфейса
Ид: 1612399b-4b7d-4dda-82e0-9d4110d9bcc8
Имя: ФормаТаблица
ОбластьВидимости: ВПодсистеме
Наследует:
    Тип: Форма
    ВключатьВАвтоИнтерфейс: Ложь
    Содержимое:
        Тип: Таблица<ДинамическийСписок>
        Имя: Сетка
        Источник:
            ОсновнаяТаблица:
                Таблица: Сотрудники
            Поля:
                -
                    Тип: ПолеДинамическогоСписка
                    Выражение: Код
                -
                    Тип: ПолеДинамическогоСписка
                    Выражение: ФИО
                -
                    Тип: ПолеДинамическогоСписка
                    Выражение: Возраст
            Порядок:
                -
                    Поле: Код
                    НаправлениеСортировки: ПоВозрастанию
        Колонки:
            -
                Тип: СтандартнаяКолонкаТаблицы<СтрокаДинамическогоСписка>
                Заголовок: Код
                ПолеЗначения: Код
            -
                Тип: СтандартнаяКолонкаТаблицы<СтрокаДинамическогоСписка>
                Заголовок: ФИО
                ПолеЗначения: ФИО
            -
                Тип: СтандартнаяКолонкаТаблицы<СтрокаДинамическогоСписка>
                Заголовок: Возраст
                ПолеЗначения: Возраст
                Коннотация: =ОформлениеКолонки(ДанныеСтроки)

В модуле формы метод ОформлениеКолонки() может выглядеть следующим образом:

метод ОформлениеКолонки(ДанныеСтроки: СтрокаДинамическогоСписка):  Коннотация
    если (ДанныеСтроки.Данные["Возраст"] как Число) < 40
        возврат Коннотация.Положительная
    иначе
        возврат Коннотация.Отрицательная
    ;
;

Возраст, полученный из соответствия Данные, нужно привести к типу Число, чтобы была возможность использовать его в операции сравнения.

Метод возвращает один из стилей оформления, которые применит к колонке таблицы.

В результате возраст меньше сорока будет показан зеленым цветом, а остальные значения — красным.

Вычисляемые выражения команд строки таблицы

При описании вычисляемых свойств команд строки таблицы (ФрагментКомандногоИнтерфейса) вы также можете использовать дополнительный параметр ДанныеСтроки. В нем содержится идентификатор строки списка или массив идентификаторов строк списка. Идентификатор строки списка зависит от типа источника:Параметр имеет тип:
  • SourceType.DataType и содержит данные строки, для которой формируется команда, если идет отображение команды в строке таблицы
  • Массив<SourceType.IdType> и содержит массив идентификаторов отмеченных строк, если данная команда отображается в панели команд над отмеченными строками (это происходит в случае автопереноса подходящих команд в команды над отмеченными строками, если они не заданы явно).

Эти данные вы можете использовать для того, чтобы выбрать подходящее оформление для команды строки списка или переопределить поведение команды в зависимости от содержимого строки, например:

ВидЭлемента: КомпонентИнтерфейса
Ид: 332157b6-92ac-47b1-a878-b1cd91955a81
Имя: МояФорма
ОбластьВидимости: ВПроекте
Свойства:
    -
        Имя: ИспользоватьКомандыНадОтмеченными
        Тип: Булево
        ЗначениеПоУмолчанию: Ложь
Наследует:
    Тип: Форма
    Заголовок: "Таблица"
    Содержимое:
        Тип: ОбычнаяГруппа
        Ориентация: Вертикальная
        Содержимое:
            -
                Тип: Флажок
                Заголовок: ИспользоватьКомандыНадОтмеченными
                Значение: =ИспользоватьКомандыНадОтмеченными
            -
                Тип: Таблица<ИсточникДанныхМассив<МояСтруктура>>
                ТолькоЧтение: Истина
                Имя: Таблица
                ИспользоватьОтметкиСтрок: Истина
                КомандыСтроки: 
                    Тип: ФрагментКомандногоИнтерфейса<КомандаСПараметром<Массив<МояСтруктура>> | КомандаСПараметром<МояСтруктура>>
                    Элементы:
                        -
                            Тип: КомандаСПараметром<МояСтруктура>
                            Представление: '= ДанныеСтроки.Статус ? "Остановить" : "Запустить"'
                            Изображение: '= ДанныеСтроки.Статус ? Ресурс{Стоп.svg}.Ссылка : Ресурс{Старт.svg}.Ссылка'
                            Обработчик: ОбработчикКоманды
                        -
                            Тип: КомандаСПараметром<Массив<МояСтруктура>>
                            Представление: =ПредставлениеМассовойКомандыСтроки(ДанныеСтроки)
                            Изображение: =ИзображениеМассовойКоманды(ДанныеСтроки)
                            Обработчик: ОбработчикМассовойКоманды
                КомандыНадОтмеченнымиСтроками: '= ИспользоватьКомандыНадОтмеченными ? КомандыНадОтмеченными(ОтмеченныеСтроки) : Неопределено'
В модуле формы методы ОбработчикКоманды и ОбработчикМассовойКоманды могут выглядеть следующим образом:
метод ОбработчикКоманды(Команда: КомандаСПараметром<МояСтруктура>, Параметр: МояСтруктура)
    Параметр.Статус = не Параметр.Статус
;    

метод ОбработчикМассовойКоманды(Команда: КомандаСПараметром<Массив<МояСтруктура>>, Параметр: Массив<МояСтруктура>)
    пер НовыйСтатус = ТолькоОстановленные(Параметр)
    для Строка из Параметр
        Строка.Статус = НовыйСтатус
    ;
;

метод ПредставлениеМассовойКомандыСтроки(ДанныеСтроки: МояСтруктура): Строка
    если ТолькоОстановленные(ДанныеСтроки)
        возврат "Запустить (команда строки)"
    иначе
        возврат "Остановить (команда строки)"
    ;
;

метод ИзображениеМассовойКоманды(ДанныеСтроки: МояСтруктура): ДвоичныйОбъект.Ссылка
    если ТолькоОстановленные(ДанныеСтроки)
        возврат Ресурс{Старт.svg}.Ссылка
    иначе
        возврат Ресурс{Стоп.svg}.Ссылка
    ;
;

метод ТолькоОстановленные(ДанныеСтроки: Массив<МояСтруктура>|МояСтруктура): Булево
    пер ТолькоОстановленные = Истина
    если ДанныеСтроки это Массив<МояСтруктура>
        для Объект из (ДанныеСтроки как Массив<МояСтруктура>)
            если Объект.Статус
                ТолькоОстановленные = Ложь
            ;
        ;
    иначе
        если (ДанныеСтроки как МояСтруктура).Статус
            ТолькоОстановленные = Ложь
        ;
    ;
    возврат ТолькоОстановленные
;

Для команд отмеченных строк вы также можете выбрать подходящее оформление или переопределить поведение команд в зависимости от данных каждой строки. Для этого в свойстве КомандыНадОтмеченнымиСтроками следует использовать параметр ОтмеченныеСтроки. Параметр имеет тип Массив<Объект?> и содержит массив идентификаторов отмеченных строк. Пример:

КомандыНадОтмеченнымиСтроками: '= ИспользоватьКомандыНадОтмеченными ? КомандыНадОтмеченными(ОтмеченныеСтроки) : Неопределено'

В модуле формы метод КомандыНадОтмеченными() может выглядеть следующим образом:

метод КомандыНадОтмеченными(ОтмеченныеСтроки: Массив<МояСтруктура>): ФрагментКомандногоИнтерфейса<КомандаСПараметром<Массив<МояСтруктура>>>
    пер ТолькоОстановленные = ТолькоОстановленные(ОтмеченныеСтроки)
    пер Представление = ТолькоОстановленные ? "Запустить (команда отмеченных)" : "Остановить (команда отмеченных)"
    пер Изображение = ТолькоОстановленные ? Ресурс{Старт.svg}.Ссылка : Ресурс{Стоп.svg}.Ссылка

    возврат новый ФрагментКомандногоИнтерфейса<КомандаСПараметром<Массив<МояСтруктура>>>(Элементы = [
        новый КомандаСПараметром<Массив<МояСтруктура>>(
            Представление = Представление,
            Изображение = Изображение,
            Обработчик = метод (Команда, Строки) ->
                для Строка из Строки
                    Строка.Статус = ТолькоОстановленные
                ;
            ;
        )
    ])
;

метод ТолькоОстановленные(ДанныеСтроки: Массив<МояСтруктура>|МояСтруктура): Булево
    пер ТолькоОстановленные = Истина
    если ДанныеСтроки это Массив<МояСтруктура>
        для Объект из (ДанныеСтроки как Массив<МояСтруктура>)
            если Объект.Статус
                ТолькоОстановленные = Ложь
            ;
        ;
    иначе
        если (ДанныеСтроки как МояСтруктура).Статус
            ТолькоОстановленные = Ложь
        ;
    ;
    возврат ТолькоОстановленные
;