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