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