При разработке интерактивных рабочих мест и чатов на управляемых формах 1С часто возникает задача: обеспечить удобный многострочный ввод текста с автоматическим переносом строк по словам (word wrap), пока форма в фоновом режиме опрашивает базу данных через обработчик ожидания. Однако разработчики сталкиваются с конфликтом двух платформенных механизмов.
Проанализируем суть возникшей проблемы:
ПолеТекстовогоДокумента (связанный с объектом ТекстовыйДокумент), то на уровне платформы в нем отсутствует «мягкий» перенос по словам. Строка переносится исключительно при нажатии клавиши Enter или программной вставке символа перевода строки (Символы.ПС).ПолеВвода со свойствами МногострочныйРежим = Истина и РасширенноеРедактирование = Истина, перенос строк работает корректно. Однако при срабатывании периодического обработчика ожидания (метод ПодключитьОбработчикОжидания), который обращается к серверу и обновляет контекст формы, незафиксированный пользовательский ввод мгновенно сбрасывается или выделяется, затирая набранный текст.Выясним физическую причину такого поведения платформы и разберем несколько практических вариантов обхода этого ограничения.
Когда пользователь набирает текст в элементе формы ПолеВвода, набранные символы попадают во внутренний клиентский буфер редактирования (свойство элемента ТекстРедактирования). Значение связанного реквизита формы при этом еще не изменено — фиксация происходит только после потери фокуса элементом, нажатия Enter или выбора значения.
Если в этот момент срабатывает обработчик ожидания, который вызывает серверную процедуру и выполняет изменение реквизитов формы на клиенте (например, перезаполняет таблицу данных), платформа инициирует синхронизацию элементов интерфейса. В процессе этой синхронизации текущее редактирование прерывается, а значение в поле ввода сбрасывается до актуального состояния реквизита формы (то есть до пустого значения или старого текста).
Рассмотрим рабочие способы решения данной задачи.
Разберем по шагам логику временной приостановки фонового опроса сервера, пока пользователь активно работает с полем ввода. Это позволяет исключить состязание между набором текста и серверной синхронизацией.
Для этого отключим обработчик ожидания в момент получения фокуса и включим его обратно при потере фокуса:
ПриАктивизации или АвтоПодбор отключаем периодический вызов с помощью ОтключитьОбработчикОжидания.ОкончаниеВводаТекста или ПриИзменении, когда данные уже зафиксированы в реквизите, снова подключаем опрос через ПодключитьОбработчикОжидания.Посмотрим на пример реализации в модуле управляемой формы:
&НаКлиенте
Процедура ПолеВводаТекстаПриАктивизации(Элемент)
// Отключаем опрос сервера на время редактирования
ОтключитьОбработчикОжидания("ПроверитьОбновленияВБазе");
КонецПроцедуры
&НаКлиенте
Процедура ПолеВводаТекстаПриИзменении(Элемент)
// Включаем опрос обратно после завершения ввода
ПодключитьОбработчикОжидания("ПроверитьОбновленияВБазе", 10);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьОбновленияВБазе()
// Проверяем, не вводит ли пользователь текст прямо сейчас
Если Элементы.ПолеВводаТекста.ТекстРедактирования <> "" Тогда
Возврат;
КонецЕсли;
ОбновитьДанныеНаСервере();
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбновитьДанныеНаСервере()
// Серверная логика получения изменений
КонецПроцедуры
Объект ФорматированныйДокумент лишен проблемы поля текстового документа — он автоматически выполняет перенос строк по границе элемента и корректно удерживает фокус при клиент-серверных взаимодействиях.
Чтобы пользователь воспринимал такое поле как обычный блок для набора заметок или сообщений, достаточно скрыть командную панель форматирования:
ФорматированныйДокумент.ПолеФорматированногоДокумента.ПолучитьТекст() объекта ФорматированныйДокумент.Если требуется строгий контроль над поведением текстового блока и гарантированная изоляция от сброса при серверных вызовах, разберем решение на базе Поля HTML-документа.
Внутрь поля загружается простая HTML-страница со стандартным элементом <textarea> или блоком contenteditable:
<textarea> изначально поддерживает перенос текста по словам и не сбрасывается механизмом управляемой формы при вызовах процедур с директивой &НаСервереБезКонтекста.document.location.href и событие ПриНажатии поля HTML-документа.Постоянный вызов сервера по таймеру каждые несколько секунд (пуллинг) создает паразитную нагрузку на сервер 1С и СУБД. Рассмотрим альтернативные платформенные механизмы доставки актуальных данных:
ДинамическийСписок со свойством АвтоДинамическоеСчитываниеДанных позволяет платформе оптимизировать чтение порций данных без сброса фокуса и буферов ввода в соседних элементах формы.