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