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