Как подключить обработчик ожидания и события для программно созданных элементов формы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки сложных интерфейсов на управляемых формах 1С часто возникает необходимость не просто создать элементы динамически, но и обеспечить их интерактивность: автоматическое обновление данных, реакцию на нажатия или изменение содержимого. Особенность управляемых форм заключается в том, что механизмы взаимодействия с динамическими объектами отличаются от работы со статичными элементами, заданными в конфигураторе.

В этой статье мы подробно разберем, как правильно организовать работу обработчиков ожидания для программных вкладок, как связывать данные с новыми полями и как назначать обработчики событий (например, при нажатии) программно созданным кнопкам или полям HTML-документа.

Особенности работы обработчиков ожидания на управляемой форме

Важно понимать фундаментальное ограничение платформы 1С:Предприятие 8.3: обработчики ожидания существуют только на уровне формы или в глобальном контексте. Нельзя подключить «индивидуальный» обработчик ожидания к конкретной кнопке, группе или странице. Обработчик всегда принадлежит всей форме целиком.

Рассмотрим ситуацию, когда мы программно создаем несколько вкладок (страниц), и нам нужно, чтобы данные на активной вкладке обновлялись каждые несколько секунд. Разберем по шагам, как это реализовать правильно.

Для начала нам необходимо создать в модуле формы клиентскую процедуру, которая будет выполнять обновление. Она должна быть определена заранее, так как динамически добавлять код процедур в модуль формы во время работы приложения невозможно.


&НаКлиенте
Процедура ОбновитьДанныеДинамическихЭлементов()
    // Здесь будет логика обновления
КонецПроцедуры

Для запуска процесса обновления используем метод ПодключитьОбработчикОжидания. Обычно это делается в процедуре ПриОткрытии или сразу после создания динамических элементов.


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем обработчик с интервалом 5 секунд
    ПодключитьОбработчикОжидания("ОбновитьДанныеДинамическихЭлементов", 5);
КонецПроцедуры

Программное создание реквизитов и элементов: важный нюанс

Прежде чем обновлять данные в программно созданном «Поле формы», нужно убедиться, что этому полю есть куда записывать данные. Просто добавить элемент через Элементы.Добавить недостаточно. Проанализируем правильный алгоритм создания:

  1. Создаем массив описаний новых реквизитов.
  2. Используем метод ИзменитьРеквизиты, чтобы добавить их в структуру формы.
  3. Добавляем элемент формы (визуальное представление).
  4. Связываем свойство ПутьКДанным элемента с созданным реквизитом.

Рассмотрим пример кода, который создает страницу и поле для текста:


&НаСервере
Процедура СоздатьДинамическиеЭлементыНаСервере()
    
    // 1. Добавляем реквизит формы для хранения данных
    МассивДобавляемыхРеквизитов = Новый Массив;
    ИмяРеквизита = "ДинамическийТекст_1";
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("Строка")));
    ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
    
    // 2. Создаем страницу (вкладку)
    ИмяСтраницы = "СтраницаДинамическая";
    НоваяСтраница = Элементы.Добавить(ИмяСтраницы, Тип("ГруппаФормы"), Элементы.ГруппаСтраницыПанели);
    НоваяСтраница.Вид = ВидГруппыФормы.Страница;
    НоваяСтраница.Заголовок = "Автообновление";
    
    // 3. Создаем поле на этой странице
    НовоеПоле = Элементы.Добавить("ПолеТекста", Тип("ПолеФормы"), НоваяСтраница);
    НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
    НовоеПоле.ПутьКДанным = ИмяРеквизита; // Привязка к созданному реквизиту
    
КонецПроцедуры

Оптимизация: обновление только активной вкладки

Если мы создадим много программных вкладок, постоянное обновление всех данных в обработчике ожидания создаст избыточную нагрузку на сервер и сеть. Выясним, как обновлять только то, что видит пользователь.

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


&НаКлиенте
Процедура ОбновитьДанныеДинамическихЭлементов()
    
    // Проверяем, какая вкладка активна в группе страниц "ГруппаПанель"
    ТекущаяВкладка = Элементы.ГруппаПанель.ТекущаяСтраница;
    
    Если ТекущаяВкладка = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Если активна наша программная вкладка, обновляем её данные
    Если ТекущаяВкладка.Имя = "СтраницаДинамическая" Тогда
        ОбновитьКонкретнуюИнформациюНаСервере();
    КонецЕсли;
    
КонецПроцедуры

Назначение обработчиков событий через УстановитьДействие

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

Рассмотрим пример назначения обработчика события ПриИзменении для динамического поля:


&НаСервере
Процедура НастроитьСобытияЭлемента(ИмяЭлемента)
    
    Элемент = Элементы[ИмяЭлемента];
    
    // Указываем имя события и имя клиентской процедуры-обработчика
    // Процедура "ОбработкаДинамическогоНажатия" должна существовать в модуле формы
    Элемент.УстановитьДействие("ПриИзменении", "ОбработкаДинамическогоНажатия");
    
КонецПроцедуры

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


&НаКлиенте
Процедура ОбработкаДинамическогоНажатия(Элемент)
    
    Сообщить("Событие вызвано элементом: " + Элемент.Имя);
    
    // В зависимости от имени выполняем разную логику
    Если Элемент.Имя = "Кнопка_Сохранить" Тогда
        // Код сохранения
    КонецЕсли;
    
КонецПроцедуры

Остановка обработчика и контроль жизненного цикла

Выясним причину возможных ошибок при закрытии вкладок. Если вы удаляете динамические элементы программно, но обработчик ожидания продолжает работать и обращаться к ним по имени, система выдаст ошибку «Объект не найден».

Чтобы избежать этого, рекомендуем два подхода:

  1. Проверка существования: Всегда проверяйте наличие элемента перед обращением к нему в обработчике:
    Если Элементы.Найти("ИмяЭлемента") <> Неопределено Тогда...
  2. Отключение обработчика: Если динамические элементы были «сердцем» формы и их удаление означает конец процесса, вызовите ОтключитьОбработчикОжидания("ИмяПроцедуры").

Особенности для Поля HTML документа

В обсуждении упоминалось использование ПолеHTMLДокумента. Это специфический объект. Если вам нужно обновлять информацию внутри него, рассмотрите возможность использования JavaScript внутри самого HTML-кода. С помощью функции setInterval в JS можно обновлять содержимое страницы без лишних вызовов серверных процедур 1С, что значительно ускорит интерфейс.

Если же данные должны приходить именно из базы 1С, то в обработчике ожидания на стороне 1С используйте метод УстановитьТекст() или работайте с Документ.getElementById, если нужно точечное обновление элементов внутри HTML-контейнера.

Резюме

Подведем итог нашему разбору. Для реализации динамического интерфейса с автообновлением необходимо:

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

← На главную