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