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