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