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