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

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

При разработке интерактивных рабочих мест и чатов на управляемых формах 1С часто возникает задача: обеспечить удобный многострочный ввод текста с автоматическим переносом строк по словам (word wrap), пока форма в фоновом режиме опрашивает базу данных через обработчик ожидания. Однако разработчики сталкиваются с конфликтом двух платформенных механизмов.

Проанализируем суть возникшей проблемы:

  1. Поле текстового документа: Если использовать элемент управления с видом ПолеТекстовогоДокумента (связанный с объектом ТекстовыйДокумент), то на уровне платформы в нем отсутствует «мягкий» перенос по словам. Строка переносится исключительно при нажатии клавиши Enter или программной вставке символа перевода строки (Символы.ПС).
  2. Многострочное поле ввода: Если переключиться на стандартное ПолеВвода со свойствами МногострочныйРежим = Истина и РасширенноеРедактирование = Истина, перенос строк работает корректно. Однако при срабатывании периодического обработчика ожидания (метод ПодключитьОбработчикОжидания), который обращается к серверу и обновляет контекст формы, незафиксированный пользовательский ввод мгновенно сбрасывается или выделяется, затирая набранный текст.

Выясним физическую причину такого поведения платформы и разберем несколько практических вариантов обхода этого ограничения.

Почему сбрасывается текст при вызове обработчика ожидания

Когда пользователь набирает текст в элементе формы ПолеВвода, набранные символы попадают во внутренний клиентский буфер редактирования (свойство элемента ТекстРедактирования). Значение связанного реквизита формы при этом еще не изменено — фиксация происходит только после потери фокуса элементом, нажатия Enter или выбора значения.

Если в этот момент срабатывает обработчик ожидания, который вызывает серверную процедуру и выполняет изменение реквизитов формы на клиенте (например, перезаполняет таблицу данных), платформа инициирует синхронизацию элементов интерфейса. В процессе этой синхронизации текущее редактирование прерывается, а значение в поле ввода сбрасывается до актуального состояния реквизита формы (то есть до пустого значения или старого текста).

Рассмотрим рабочие способы решения данной задачи.

Вариант 1. Управление обработчиком ожидания при активности поля ввода

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

Для этого отключим обработчик ожидания в момент получения фокуса и включим его обратно при потере фокуса:

  1. В событии элемента ПриАктивизации или АвтоПодбор отключаем периодический вызов с помощью ОтключитьОбработчикОжидания.
  2. В событии ОкончаниеВводаТекста или ПриИзменении, когда данные уже зафиксированы в реквизите, снова подключаем опрос через ПодключитьОбработчикОжидания.

Посмотрим на пример реализации в модуле управляемой формы:


&НаКлиенте
Процедура ПолеВводаТекстаПриАктивизации(Элемент)
    // Отключаем опрос сервера на время редактирования
    ОтключитьОбработчикОжидания("ПроверитьОбновленияВБазе");
КонецПроцедуры

&НаКлиенте
Процедура ПолеВводаТекстаПриИзменении(Элемент)
    // Включаем опрос обратно после завершения ввода
    ПодключитьОбработчикОжидания("ПроверитьОбновленияВБазе", 10);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьОбновленияВБазе()
    // Проверяем, не вводит ли пользователь текст прямо сейчас
    Если Элементы.ПолеВводаТекста.ТекстРедактирования <> "" Тогда
        Возврат;
    КонецЕсли;
    
    ОбновитьДанныеНаСервере();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ОбновитьДанныеНаСервере()
    // Серверная логика получения изменений
КонецПроцедуры

Вариант 2. Использование форматированного документа без панели инструментов

Объект ФорматированныйДокумент лишен проблемы поля текстового документа — он автоматически выполняет перенос строк по границе элемента и корректно удерживает фокус при клиент-серверных взаимодействиях.

Чтобы пользователь воспринимал такое поле как обычный блок для набора заметок или сообщений, достаточно скрыть командную панель форматирования:

  1. Добавим на форму реквизит с типом ФорматированныйДокумент.
  2. Создадим элемент формы с видом ПолеФорматированногоДокумента.
  3. В свойствах элемента снимем флаги отображения командной панели и контекстного меню форматирования (или отключим видимость кнопок стиля, шрифта и цвета).
  4. При чтении и сохранении данных конвертируем содержимое в обычный текст с помощью метода ПолучитьТекст() объекта ФорматированныйДокумент.

Вариант 3. Использование Поля HTML-документа

Если требуется строгий контроль над поведением текстового блока и гарантированная изоляция от сброса при серверных вызовах, разберем решение на базе Поля HTML-документа.

Внутрь поля загружается простая HTML-страница со стандартным элементом <textarea> или блоком contenteditable:

  1. HTML-элемент <textarea> изначально поддерживает перенос текста по словам и не сбрасывается механизмом управляемой формы при вызовах процедур с директивой &НаСервереБезКонтекста.
  2. Передача набранного текста в контекст 1С выполняется либо по явной команде отправки, либо через механизм document.location.href и событие ПриНажатии поля HTML-документа.

Вариант 4. Архитектурный переход на Систему взаимодействия или Динамический список

Постоянный вызов сервера по таймеру каждые несколько секунд (пуллинг) создает паразитную нагрузку на сервер 1С и СУБД. Рассмотрим альтернативные платформенные механизмы доставки актуальных данных:

  1. Система взаимодействия (Push-модель): Вместо опроса базы по таймеру используется штатная система взаимодействия. При записи данных в регистр отправляется оповещение, а на клиенте срабатывает обработчик входящего сообщения, обновляя интерфейс только в момент реального появления новых записей.
  2. Динамический список с автообновлением: Если на форме отображаются записи регистра, замена ручной таблицы значений на ДинамическийСписок со свойством АвтоДинамическоеСчитываниеДанных позволяет платформе оптимизировать чтение порций данных без сброса фокуса и буферов ввода в соседних элементах формы.
  3. Кнопка ручного обновления: Если бизнес-требования допускают отказ от жесткого реального времени, добавление стандартной кнопки «Обновить» полностью устраняет конфликт пользовательского ввода с фоновыми процессами.
← На главную