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