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