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