Как настроить поле HTML-документа для редакторов кода и сохранить состояние с циклическими ссылками в 1С?

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

При создании сложных пользовательских интерфейсов в 1С — например, встроенных редакторов кода с подсветкой синтаксиса на JS (CodeMirror, Ace) или при реализации собственных интерпретаторов — разработчики часто сталкиваются с двумя фундаментальными проблемами. Первая — блокировка клавиш навигации (стрелок) внутри элемента Поле HTML-документа. Вторая — невозвожность сохранить состояние (State), содержащее циклические ссылки, стандартными средствами платформы 1С на сервере.

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

Причины проблем с навигацией в поле HTML-документа и их устранение

Рассмотрим, почему в поле HTML-документа перестают работать клавиши со стрелками, Home, End или Tab. Системная обертка 1С перехватывает клавиши управления курсором для переключения фокуса между элементами самой формы. Из-за этого события клавиатуры не доходят до внутреннего контекста браузера и подключенного JavaScript-редактора.

Кроме того, в устаревших версиях платформы (или при работе в режиме совместимости) поле HTML использует старый движок Trident в режиме эмуляции IE7, где обработка событий keydown и keyup работает некорректно.

Для решения проблемы с управлением курсором и вводом текста разберем следующие шаги:

  1. Переход на платформу 8.3 с новым движком. В актуальных версиях платформы 1С 8.3 устаревший движок Internet Explorer заменен на встроенный Chromium (CEF). В нем обработка клавиатурных событий и навигация курсора внутри сторонних JS-редакторов выполняются нативно без дополнительного вмешательства.
  2. Перевод элемента в режим эмуляции IE11 (для платформ на Trident). Если разработка ведетcя на операционной системе Windows со старыми релизами платформы, необходимо принудительно переключить режим эмуляции браузера в системном реестре. Для этого в ветке:

    HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

    создается параметр типа DWORD с именем исполняемого файла (1cv8.exe или 1cv8c.exe) и значением 11001 (десятичное) или 11000. Это включает полноценную поддержку стандарта IE11.
  3. Вызов команд редактора напрямую из 1С. Если перехват клавиш платформой обойти не удается, можно связать действия навигации с кнопками формы 1С или комбинациями клавиш. Для передачи команд в JavaScript используется метод ИсполнитьСценарий():
    
    // Вызов JS-функции сдвига курсора в редакторе CodeMirror
    Элементы.ПолеHTML.ИсполнитьСценарий("editor.execCommand('goCharLeft');");
    

Проблема хранения состояния с циклическими ссылками на сервере

Проанализируем вторую проблему: сохранение сложных коллекций (объектов типов Структура и Соответствие) на сервере между вызовами веб-сервисов или HTTP-запросов.

Попытка записать структуру с циклическими ссылками в ХранилищеЗначения или выполнить ЗначениеВСтрокуВнутр() приводит к аварийному завершению сеанса с ошибкой переполнения стека (Stack Overflow). Это происходит потому, что штатный сериализатор 1С выполняет рекурсивный обход всех вложенных элементов и попадает в бесконечный цикл.

Посмотрим на пример структуры с циклической ссылкой:


Состояние = Новый Соответствие;
Узел = Новый Структура("Родитель", Состояние);

// Создание циклической ссылки
Состояние.Вставить("Узел", Узел);

Варианты архитектурных решений для сохранения серверного состояния

Разберем основные способы, которые позволяют корректно работать со сложным состоянием на сервере 1С:

  1. Нормализация графа (дециклизация) перед сериализацией. Для сохранения структуры на диск или в базу данных прямые ссылки между объектами заменяются уникальными идентификаторами (ID). Вместо вложенного графа создается плоская карта узлов (список смежности).

    Перед сохранением выполняем замену всех объектных ссылок на их ключи, сериализуем полученный массив в JSON или ХранилищеЗначения, а при чтении выполняем обратное восстановление указателей в памяти.

  2. Использование временного хранилища. Если данные требуется передавать в рамках одного пользовательского сеанса между вызовами, используем функции ПоместитьВоВременноеХранилище() и ПолучитьИзВременноеХранилище(). Это позволяет удерживать данные в оперативной памяти сервера, связывая их с уникальным адресом:
    
    // Сохранение адреса во временном хранилище
    АдресСостояния = ПоместитьВоВременноеХранилище(Состояние, УникальныйИдентификатор);
    
    // Получение данных обратно в сеансе
    Состояние = ПолучитьИзВременноеХранилище(АдресСостояния);
    
  3. Кэширование через повторное использование возвращаемых значений. Для модулей платформы можно включить свойство Повторное использование возвращаемых значений ("На время вызова" или "На время сеанса"). Это позволяет мемоизировать результаты вычислений и не производить повторную сериализацию сложных объектов при частых обращениях.
  4. Сохранение сеанса веб-сервиса (IBSession). При работе через SOAP или HTTP-сервисы 1С по умолчанию каждый запрос обрабатывается без сохранения состояния (stateless). Чтобы удерживать объекты в памяти между вызовами, в файле публикации default.vrd настраивается параметр reuseSessions="use". Клиент передает HTTP-заголовок IBSession, благодаря чему все последующие запросы попадают в один и тот же рабочий процесс сервера, сохраняя переменные модуля.

Таким образом, сочетание обновления платформы, корректной настройки эмуляции браузера и нормализации структур данных позволяет создавать удобные интерфейсы с внешними JS-компонентами и надежно работать со сложным сервером состояний в 1С.

← На главную