Как правильно вызвать и настроить обработчик ПриПолученииДанныхНаСервере для динамического списка

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с управляемыми формами в «1С:Предприятие 8.3» разработчики часто сталкиваются с необходимостью динамического изменения оформления строк или вычисления дополнительных данных непосредственно в момент отображения списка. В обычных формах для этого использовалось событие ПриПолученииДанных, однако в управляемом интерфейсе логика работы существенно изменилась. Рассмотрим, как правильно использовать серверный обработчик ПриПолученииДанныхНаСервере, как инициировать его вызов и как передавать в него параметры, учитывая бесконтекстный характер выполнения.

Различия между обычными и управляемыми формами

Первое, что нам необходимо проанализировать — это архитектурное различие. Событие ПриПолученииДанных (на клиенте) характерно для обычных форм. В управляемых формах для динамического списка используется ПриПолученииДанныхНаСервере. Важно понимать, что этот обработчик вызывается платформой автоматически при каждой порции данных, запрашиваемой списком (например, при прокрутке или принудительном обновлении).

Особенности этого события:

  1. Оно всегда выполняется в контексте &НаСервереБезКонтекста. Это означает, что внутри процедуры мы не имеем доступа к реквизитам формы напрямую (через ЭтаФорма или просто по имени реквизита).
  2. Оно вызывается только тогда, когда динамический список действительно считывает данные из базы данных.
  3. Результаты работы обработчика не записываются в базу данных, они предназначены только для визуального отображения в текущем сеансе пользователя.

Способы принудительного вызова обработчика

Если нам нужно вызвать это событие программно (например, пользователь нажал на флажок «Показать подробности»), мы должны заставить динамический список пересчитать свои данные. Рассмотрим, какие методы для этого подходят, а какие — нет.

Разберем типичную ситуацию: у нас есть команда или событие изменения элемента формы, после которого список должен обновиться. Посмотрим на код процедуры, которая инициирует обновление:


&НаКлиенте
Процедура ПоказыватьПодробностиПриИзменении(Элемент)
    ОбновитьСписокНаСервере();
КонецПроцедуры

&НаСервере
Процедура ОбновитьСписокНаСервере()
    // Использование метода Обновить() для элемента формы
    Элементы.СписокЗаявок.Обновить();
КонецПроцедуры

Метод Элементы.ИмяСписка.Обновить() является наиболее корректным способом. Он сообщает системе, что кэш данных списка недействителен, и инициирует повторный запрос к серверу. Именно этот повторный запрос и вызывает нужный нам обработчик ПриПолученииДанныхНаСервере.

Проанализируем другие варианты, которые часто пробуют новички:

Передача параметров в бесконтекстный обработчик

Так как процедура ЗаявкиПриПолученииДанныхНаСервере помечена директивой &НаСервереБезКонтекста, мы не можем просто прочитать значение флажка из реквизита формы. Нам нужно передать это значение «внутри» самого объекта списка. Рассмотрим два основных способа.

Способ 1: Использование параметров компоновки данных

Это классический путь, если логика списка завязана на запрос. Мы устанавливаем параметр в КомпоновщикНастроек, и этот параметр становится доступен в обработчике через структуру Настройки.


&НаСервере
Процедура УстановитьПараметрСписка()
    НовоеЗначение = Объект.ПоказыватьПодробности;
    Параметр = Список.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПоказыватьПодробности"));
    Если Параметр <> Неопределено Тогда
        Параметр.Значение = НовоеЗначение;
        Параметр.Использование = Истина;
    КонецЕсли;
    Элементы.Список.Обновить();
КонецПроцедуры

Однако здесь кроется ловушка: если вы программно меняете ФиксированныеНастройки, а пользователь или система уже установили такой же параметр в Настройках, возникнет ошибка: «Невозможно применить фиксированные настройки. Совпадают значения параметра». Чтобы избежать этого, рекомендуется работать либо только с текущими настройками, либо использовать более гибкий механизм.

Способ 2: Дополнительные свойства (Рекомендуемый)

Как мы выяснили в ходе анализа темы, использование ДополнительныеСвойства компоновщика настроек — это самый эффективный и «чистый» способ передачи служебных флагов. Эти свойства не влияют на сам SQL-запрос, но доступны в серверном обработчике.

Рассмотрим реализацию этого метода по шагам:

Шаг 1. Установка свойства при изменении флага на форме:


&НаСервере
Процедура ПоказыватьПодробностиПриИзмененииНаСервере()
    // Записываем значение в ДополнительныеСвойства компоновщика
    Список.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("ПоказыватьПодробности", ПоказыватьПодробности);
    
    // Принудительно обновляем список
    Элементы.Список.Обновить();
КонецПроцедуры

Шаг 2. Чтение свойства в обработчике ПриПолученииДанныхНаСервере:


&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
    
    // Получаем наш флаг из ДополнительныхСвойств настроек
    ПоказыватьПодробности = Ложь;
    Настройки.ДополнительныеСвойства.Свойство("ПоказыватьПодробности", ПоказыватьПодробности);
    
    Если ПоказыватьПодробности Тогда
        Для Каждого СтрокаСписка Из Строки Цикл
            // Ключ - ссылка или уникальный идентификатор строки
            // Значение - ДанныеСтрокиДинамическогоСписка
            Данные = СтрокаСписка.Значение.Данные;
            
            // Здесь выполняем логику, например, вычисляем признак
            Данные.ВыгружатьВРеестр = Истина; 
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Важные замечания по производительности

Разберем ситуацию, когда список содержит тысячи строк. Обработчик ПриПолученииДанныхНаСервере вызывается порциями (например, по 30-50 строк за раз). Крайне важно помнить следующее:

  1. Никаких запросов в цикле! Если вам нужно получить дополнительные данные из базы (например, остатки товаров), соберите все ссылки из параметра Строки в массив, выполните ОДИН запрос ко всей порции данных, а затем распределите результаты по строкам.
  2. Минимизируйте вычисления. Любая задержка в этой процедуре приведет к тому, что интерфейс пользователя будет «подтормаживать» при скроллинге списка.
  3. Проверка на пустоту. Обработчик вызывается только в том случае, если в списке есть хотя бы одна строка. Если список пуст, событие не сработает.

Выясним причину, почему точка останова может не срабатывать. Если вы установили точку останова в бесконтекстной процедуре и вызываете Обновить(), но ничего не происходит — проверьте, привязано ли событие в свойствах элемента формы Список на вкладке «События». Поле ПриПолученииДанныхНаСервере должно содержать имя вашей процедуры.

Резюме

Для успешного вызова обработчика и корректной работы списка мы должны:

Используя эти рекомендации, вы сможете создавать отзывчивые и функциональные интерфейсы, которые динамически подстраиваются под требования пользователя без лишней нагрузки на сервер.

← На главную