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