При разработке интерфейсов на управляемых формах 1С программисты часто сталкиваются с ситуацией, когда у элемента, который, казалось бы, предназначен только для чтения, обнаруживаются события, характерные для интерактивного ввода данных. Одним из таких примеров является Поле надписи. Если мы выведем реквизит на форму и установим ему вид Поле надписи, в списке доступных событий мы увидим ПриИзменении. На первый взгляд это кажется логической ошибкой разработчиков платформы, ведь пользователь не может вручную отредактировать текст в надписи. Однако за этим кроется определенная архитектурная логика платформы 1С:Предприятие 8.3.
В этой статье мы подробно разберем, почему это событие присутствует в палитре свойств, в чем принципиальная разница между «полем» и «декорацией», и в каких сценариях наличие этого обработчика может быть оправдано.
Прежде всего, проанализируем разницу между двумя визуально похожими элементами управления. Это поможет понять, откуда у одного из них берутся «лишние» события.
Заголовок. У декорации действительно нет события ПриИзменении, так как она не хранит данные и не предназначена для их отображения из базы данных.Рассмотрим ситуацию: мы создаем реквизит формы ДатаВылета с типом Дата. Когда мы перетаскиваем его на форму, платформа по умолчанию создает элемент с видом Поле ввода. Если мы решим изменить его визуальное представление на Поле надписи, объект в метаданных формы все равно останется типом ПолеФормы.
Выясним причину сохранения события через призму архитектуры платформы. В 1С свойства и события элементов формы жестко привязаны к их базовым классам. Объект ПолеФормы является универсальным контейнером. У него есть базовый набор событий, таких как ПриИзменении, Нажатие, ОбработкаНавигационнойСсылки.
Когда разработчик меняет свойство Вид элемента с Поле ввода на Поле надписи, платформа скрывает некоторые специфические события (например, связанные с выбором из списка или началом редактирования), но оставляет базовое событие ПриИзменении. Это происходит по нескольким причинам:
Поле ввода, все ранее назначенные обработчики должны остаться на месте. Платформа «не хочет» удалять ваш код или связи событий при простом изменении визуального представления.Разберем по шагам, может ли это событие вообще выполниться. Важно помнить постулат 1С: событие ПриИзменении на стороне клиента генерируется только при интерактивном изменении данных пользователем.
Если мы программно меняем значение реквизита в коде:
&НаКлиенте
Процедура ИзменитьДанные()
Объект.ИмяРеквизита = "Новое значение";
КонецПроцедуры
В этом случае событие ПриИзменении у элемента формы не вызовется. Это стандартное поведение платформы для всех типов полей.
Однако существуют специфические (хотя и редкие) сценарии использования:
Проанализируем ситуацию, когда одно и то же поле в зависимости от прав доступа или условий задачи меняет свой вид. Например, для обычного пользователя это надпись, а для администратора — поле ввода.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если РольДоступна("ПолныеПрава") Тогда
Элементы.ДатаДокумента.Вид = ВидПоляФормы.ПолеВвода;
Иначе
Элементы.ДатаДокумента.Вид = ВидПоляФормы.ПолеНадписи;
КонецЕсли;
КонецПроцедуры
В такой модели разработчику удобно иметь один и тот же обработчик ПриИзменении, который назначен в конфигураторе один раз. Если поле стало «вводом», событие работает. Если стало «надписью» — оно просто «висит» в метаданных, не мешая работе и не требуя удаления кода.
Иногда Поле надписи используется как гиперссылка. Хотя для реакции на нажатие существует событие Нажатие, в старых версиях платформы или при определенных комбинациях свойств (например, при использовании расширений формы) разработчики пытались использовать ПриИзменении для отслеживания состояния фокуса или связанных данных, но это скорее относится к нестандартным обходным путям (workarounds).
Большинство опытных разработчиков сходятся во мнении, что наличие этого события — это результат упрощения интерфейса «Пофигуратора» (Конфигуратора). Разработчикам платформы проще оставить это событие видимым для всех объектов типа ПолеФормы, чем прописывать сложные условия видимости каждого отдельного свойства в палитре в зависимости от выбранного «Вида» поля.
Резюмируем важные моменты:
ПриИзменении у Поля надписи — это «наследство» от базового объекта ПолеФормы.Поле надписи с Декорацией. У декорации этого события нет и быть не может.ПриИзменении самого реквизита на сервере (в модуле объекта) или вызывайте нужные процедуры явно после присваивания значения.Таким образом, мы видим, что 1С сохраняет избыточность в свойствах элементов формы ради гибкости и универсальности внутренней архитектуры управляемых форм. Это не мешает работе приложения, хотя и может вызвать легкое замешательство у начинающих разработчиков.