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