https://xn----1-bedvffifm4g.xn--p1ai/news/%D0%BE%D1%82%D0%BA%D0%B0%D0%B7-%D0%BE%D1%82-%D0%BC%D0%BE%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85-%D0%BE%D0%BA%D0%BE%D0%BD-%D0%B2-1%D1%81-8-3/
Застосовність У статті розглядається асинхронна модель побудови бізнес-логіки, додана до платформи «1С:Підприємство» редакції 8.3. Наведена інформація актуальна для поточних релізів платформи. Відмова від використання модальних вікон у платформі 1С:Підприємство 8.3 Під час розробки конфігурації на платформі 1С:Підприємство 8 періодично виникає потреба призупинити роботу програми до того моменту, коли користувач ухвалить якесь рішення або виконає якісь дії. Наприклад, при натисканні на кнопку заповнення табличної частини в користувача слід запитати, чи потрібно очистити табличну частину, щоб не сталося втрати раніше введених даних. Таку поведінку може забезпечити, наприклад, наступний код: &НаКлиенте Процедура ЗаполнитьТовары(Команда) Ответ = Вопрос(“Табличная часть будет очищена. Продолжить?”, РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Да Тогда //алгоритм заполнения КонецЕсли; КонецПроцедуры В результаті роботи цього фрагмента коду відбудеться призупинення виконання програмного коду, на екрані відображається питання, інтерфейс додатка крім діалогу з питанням стає недоступним, система очікує ухвалення рішення користувачем, виконання коду продовжиться тільки після відповіді на питання. Також до призупинення виконання коду і блокування інтерфейсу призводить відкриття модальних вікон за допомогою виклику методу ОткрытьМодально(). При роботі з конфігурацією в режимі веб-клієнта через браузер у цьому випадку буде відкрито нове вікно – спливаюче вікно, яке заблокує не тільки поточну вкладку, а й весь інтерфейс браузера, включаючи інші відкриті вікна та вкладки. Спливаючі вікна в Інтернеті часто використовуються для зловмисного розповсюдження небажаної реклами, тому браузери містять функції блокування спливаючих вікон. У такому разі для роботи з конфігураціями 1С:Підприємство 8 через браузер необхідно заборонити блокування спливаючих вікон. Проблеми також виникають при роботі на мобільних пристроях. Так, наприклад, модальні вікна не підтримуються на iPad. Для вирішення зазначених проблем слід використовувати блокуючі вікна замість модальних. Для користувача візуально все виглядає так само: вікно блокує інтерфейс веб-клієнта. Однак блокуюче вікно як би “малюється” поверх головного вікна, і блокується тільки поточна вкладка браузера, в якій відкрита конфігурація, дозволяючи перемикатися на інші вкладки, оскільки модальні вікна браузера при цьому не використовуються. Таким чином, спливаючі вікна в браузері не відкриваються і забезпечується робота через веб-клієнт на мобільних пристроях. У кореневого елемента конфігурації існує властивість “Режим использования модальности”, яка визначає, чи можна в конфігурації відкривати модальні вікна. Якщо вибрано варіант “Использовать”, то модальні вікна можна відкривати. Якщо вибрано варіант “Не использовать”, то модальні вікна неприпустимі. При спробі викликати метод, що відкриває модальне вікно, система виводить повідомлення про помилку: При такому значенні властивості “Режим использования модальности” допустимі тільки блокуючі вікна. Якщо вибрано варіант “Использовать с предупреждениями”, то при відкритті модальних вікон у вікно повідомлень виводиться текст: Такий варіант роботи може використовуватися як проміжний при переробці конфігурації з метою відмови від використання модальних вікон. Основна відмінність блокуючих вікон від модальних полягає в тому, що відкриття блокуючого вікна не спричиняє призупинення виконання коду. Тому розробникам доведеться переписати програмний код, що використовує модальні вікна, з урахуванням цієї особливості. Код потрібно розділити на дві частини: відкриття блокуючого вікна; обробка вибору користувача. Фрагмент коду, наведений на початку статті, потрібно переписати таким чином: &НаКлиенте Процедура ЗаполнитьТовары(Команда) Оповещение = Новый ОписаниеОповещения(“ЗаполнитьТоварыВопросЗавершение”, ЭтотОбъект); ТекстВопроса = “Табличная часть будет очищена. Продолжить?”; ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет); КонецПроцедуры &НаКлиенте Процедура ЗаполнитьТоварыВопросЗавершение(Результат, ДополнительныеПараметры) Экспорт Если Результат = КодВозвратаДиалога.Да Тогда //алгоритм заполнения КонецЕсли; КонецПроцедуры Після виконання процедури ПоказатьВопрос() система не зупиняється, очікуючи відповіді користувача, виконання коду продовжується. Користувач зможе зробити вибір тільки після завершення роботи всієї процедури. При цьому буде викликана експортна процедура ЗаполнитьТоварыВопросЗавершение(). Її назву ми передали в конструктор об'єкта ОписаниеОповещения. Процедура, яка буде викликана після здійснення вибору, може бути розташована в модулі форми, модулі команди, загальному не глобальному модулі. У розглянутому прикладі викликана процедура розташована в модулі керованої форми, тому ми передали в параметр ЭтотОбъект. Розглянемо виклик процедури, розташованої в загальному модулі. Для цього додамо новий загальний модуль ОбработкаОповещений, встановимо для нього прапорець “Клиент (управляемое приложение)”, а ознаку “Глобальный” не встановлюємо. Розташуємо в цьому модулі процедуру ЗаполнитьТоварыВопросЗавершение(). Тоді обробник команди заповнення буде виглядати так: &НаКлиенте Процедура ЗаполнитьТовары(Команда) Оповещение = Новый ОписаниеОповещения(“ЗаполнитьТоварыВопросЗавершение”, ОбработкаОповещений); ТекстВопроса = “Табличная часть будет очищена. Продолжить?”; ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет); КонецПроцедуры Після виклику будь-якого методу, що відкриває блокуюче вікно, процедура повинна завершуватися, а виконуваний далі код слід розташовувати в процедурі, яка буде викликана після закриття вікна. Для передачі контексту (допоміжних даних, якихось параметрів, значень змінних) з процедури, що відкриває модальне вікно, в процедуру, що викликається при його закритті, передбачено третій необов'язковий параметр конструктора об'єкта ОписаниеОповещения – ДополнительныеПараметры. Цей об'єкт (будь-якого типу) буде передано в процедуру, описану в ОписаниеОповещения, останнім параметром. На прикладі розглянутої вище ділянки коду це можна зробити так: &НаКлиенте Процедура ЗаполнитьТовары(Команда) Параметр1 = 0; Параметр2 = 0; СписокПараметров = Новый Структура(“Параметр1, Параметр2″, Параметр1, Параметр2); Оповещение = Новый ОписаниеОповещения(“ЗаполнитьТоварыВопросЗавершение”, ЭтотОбъект, СписокПараметров); ПоказатьВопрос(Оповещение, “Табличная часть будет очищена. Продолжить?”, РежимДиалогаВопрос.ДаНет); КонецПроцедуры &НаКлиенте Процедура ЗаполнитьТоварыВопросЗавершение(Результат, ДополнительныеПараметры) Экспорт Если Результат = КодВозвратаДиалога.Да Тогда //анализируем ДополнительныеПараметры.Параметр1 //анализируем ДополнительныеПараметры.Параметр2 КонецЕсли; КонецПроцедуры Якщо потрібно передати тільки одне значення, то структуру можна не використовувати, а присвоїти це значення параметру ДополнительныеПараметры конструктора об'єкта ОписаниеОповещения. Розглянемо кілька прикладів роботи з блокуючими вікнами. Задача 1. Відкриття іншої форми З форми документа при натисканні на кнопку “Открыть параметры” потрібно відкрити форму, на якій розташовані два прапорці Параметр1 і Параметр2, які повинен встановити користувач. Після закриття форми вивести в рядок повідомлень значення параметрів. Створюємо загальну форму “ФормаПараметров”, на якій розміщуємо реквізити Параметр1 і Параметр2, а також команду ЗакрытьФорму: Обробник команди виглядає наступним чином: Обробник команди виглядає наступним чином: &НаКлиенте Процедура ЗакрытьФорму(Команда) СписокПараметров = Новый Структура(“Параметр1, Параметр2”, Параметр1, Параметр2); Закрыть(СписокПараметров); КонецПроцедуры Для форми властивість РежимОткрытияОкна встановлюємо в “Блокировать весь интерфейс”: На формі документа розміщуємо команду ОткрытьПараметры, обробник якої описуємо наступним чином: &НаКлиенте Процедура ОткрытьПараметры(Команда) Оповещение = Новый ОписаниеОповещения(“ОткрытьПараметрыЗавершение”, ЭтотОбъект); ОткрытьФорму(“ОбщаяФорма.ФормаПараметров”, , , , , , Оповещение); КонецПроцедуры &НаКлиенте Процедура ОткрытьПараметрыЗавершение(Результат, ДополнительныеПараметры) Экспорт Если ТипЗнч(Результат) = Тип(“Структура”) Тогда Для каждого КлючЗначение Из Результат Цикл Сообщение = Новый СообщениеПользователю; Сообщение.Текст = “Ключ: “”” + КлючЗначение.Ключ + “””, значение = ” + КлючЗначение.Значение; Сообщение.Сообщить(); КонецЦикла; КонецЕсли; КонецПроцедуры У користувацькому режимі, запускаючи конфігурацію під веб-клієнтом, отримуємо такі результати роботи: Для збільшення натисніть на зображення. Режим відкриття вікна можна також вказувати в останньому параметрі процедури ОткрытьФорму. &НаКлиенте Процедура ОткрытьПараметры(Команда) Оповещение = Новый ОписаниеОповещения(“ОткрытьПараметрыЗавершение”, ЭтотОбъект); ОткрытьФорму(“ОбщаяФорма.ФормаПараметров”, , , , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс); КонецПроцедуры Задача 2. Питання при закритті форми При закритті вікна обробки задавати користувачеві питання, чи дійсно він хоче закрити вікно. Цю задачу можна вирішити за допомогою наступного коду, розташованого в модулі форми обробки: &НаКлиенте Перем НужноЗакрыватьФорму; &НаКлиенте Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка) Если НЕ НужноЗакрыватьФорму = Истина Тогда Отказ = Истина; Оповещение = Новый ОписаниеОповещения(“ПередЗакрытиемЗавершение”, ЭтотОбъект); ПоказатьВопрос(Оповещение, “Вы действительно хотите закрыть окно?”, РежимДиалогаВопрос.ДаНет); КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ПередЗакрытиемЗавершение(Результат, ДополнительныеПараметры) Экспорт Если Результат = КодВозвратаДиалога.Да Тогда НужноЗакрыватьФорму = Истина; Закрыть(); Иначе НужноЗакрыватьФорму = Неопределено; КонецЕсли; КонецПроцедуры У процедурі ПередЗакрытием форми користувачеві задається питання, прапорець Отказ виставляється в Истина, закриття форми скасовується. Після ствердної відповіді на питання змінна НужноЗакрыватьФорму встановлюється в Истина, форма закривається повторно. Задача 3. Введення числового значення При натисканні на кнопку на формі обробки відкривати стандартний діалог введення числа. Для цього необхідно скористатися методом ПоказатьВводЧисла() замість ВвестиЧисло(), який відкриває блокуюче вікно замість модального. &НаКлиенте Процедура ВводЧисла(Команда) Оповещение = Новый ОписаниеОповещения(“ВводЧислаЗавершение”, ЭтотОбъект); ПоказатьВводЧисла(Оповещение, 0, “Введите количество”, 15, 3); КонецПроцедуры &НаКлиенте Процедура ВводЧислаЗавершение(Результат, ДополнительныеПараметры) Экспорт Если НЕ Результат = Неопределено Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = “Вы ввели количество ” + Результат; Сообщение.Сообщить(); КонецЕсли; КонецПроцедуры Після закриття вікна введення числа буде викликана процедура, в перший параметр якої буде передано введене число або значення Неопределено, якщо користувач відмовився від введення. Задача 4. Вибір кольору При натисканні на кнопку на формі обробки за допомогою стандартного діалогу вибору кольору користувач вказує необхідний колір. Цей колір встановити для фону натисканої кнопки. Додамо на форму команду ВыборЦвета з наступним обробником: &НаКлиенте Процедура ВыборЦвета(Команда) ДиалогВыбораЦвета = Новый ДиалогВыбораЦвета; Оповещение = Новый ОписаниеОповещения(“ВыборЦветаЗавершение”, ЭтотОбъект); ДиалогВыбораЦвета.Показать(Оповещение); КонецПроцедуры &НаКлиенте Процедура ВыборЦветаЗавершение(Результат, ДополнительныеПараметры) Экспорт Если НЕ Результат = Неопределено Тогда Элементы.ВыборЦвета.ЦветФона = Результат; КонецЕсли; КонецПроцедуры Для об'єктів ДиалогВыбораЦвета (а також ДиалогРедактированияСтандартногоПериода, КонструкторФорматнойСтроки, ДиалогРасписанияРегламентногоЗадания, ДиалогВыбораШрифта) метод Показать() відкриває блокуюче вікно. Після закриття вікна буде викликана процедура, в перший параметр якої буде передано вибране значення (колір, шрифт тощо) або значення Неопределено, якщо користувач відмовився від вибору. Слід звернути увагу, що об'єкт ДиалогВыбораФайла не має методу Показать() на відміну від діалогів вибору кольору або шрифту, оскільки реалізація цих діалогів істотно різна. Для використання діалогу вибору файлу на веб-клієнті необхідно попередньо підключити розширення роботи з файлами. Діалоги, що реалізуються через розширення роботи з файлами, не створюють таких проблем у роботі, як модальні вікна браузерів, тому не було реалізовано відкриття блокуючих вікон для об'єкта ДиалогВыбораФайла. На закінчення зазначимо, що починаючи з релізу 8.3.10 у веб-клієнті припинено підтримку модальних вікон. У цьому випадку, якщо в конфігурації відбувається виклик модального методу, то відбувається генерація винятку. Також у в веб-клієнті припинено підтримку режиму інтерфейсу В отдельных окнах. Крім того, і в тонкому, і в веб-клієнті тепер не можна відкривати форму в окремому вікні (при роботі в режимі інтерфейсу В Закладках). Такі кардинальні кроки дозволили відмовитися від режиму інтерфейсу, який вже не підтримується всіма сучасними браузерами. Який практичний висновок можна зробити з цієї інформації? А висновок досить простий – якщо з якоїсь причини у вашій конфігурації досі існують модальні виклики, то в цих місцях у в веб-клієнті буде видаватися вікно з повідомленням про помилку. Хочеться застерегти від спроб “нагуглити” якесь швидке рішення цієї проблеми, т.к. основна маса порад зводиться до такого рецепту: в конфігураторі на рівні конфігурації у властивості «Режим использования модальности» поставити значення «Использовать». Природно, на цей момент, це працювати не буде тільки через те, що самі сучасні браузери вже не підтримують модальні виклики. І у вас є всього два шляхи, яким чином вирішити описану вище проблему: Оновити платформу до релізу 8.3.10+ (8.3.11), встановити властивість конфігурації «Режим совместимости» в «Не использовать» і переписати фрагменти коду, що використовують модальні методи на асинхронну модель побудови бізнес-логіки Рекомендувати вашим клієнтам користуватися застарілими браузерами, де модальні виклики ще підтримувалися (Mozilla Firefox версії 37 і нижче, Chrоme нижче 37 версії тощо). До речі, починаючи з релізу 8.3.11, більше не підтримуються веб-браузери Microsoft Internet Explorer версій 8 і 9. З веб-браузерами у світлі модальності ми розібралися, тепер настала пора прояснити ситуацію і з іншими клієнтами. Починаючи з версії 8.3.5 властивість «Режим использования модальности» в тонкому і товстому клієнтах враховується, тільки якщо вказано параметр командного рядка /EnableCheckModal. Цей параметр автоматично підставляється в командний рядок тільки при запуску додатка з конфігуратора. Якщо ж цей параметр не вказано, то генерація винятків не відбувається і відповідні попередження не показуються. Тобто на практиці в разі використання товстого і тонкого клієнта ніякої кардинальної зміни в роботі при використанні режиму модальності не спостерігається – модальні виклики будуть працювати так само, як і працювали раніше, при цьому не видаючи ніяких попереджень, як у веб-клієнті. Щоб розставити всі крапки над “i”, зауважимо, що починаючи з редакції 8.3.9 у товстому клієнті ігнорується властивість конфігурації «Режим использования синхронных вызовов расширений платформы и внешних компонент», при цьому відповідні синхронні методи працюють без генерації винятків і виведення попереджень. Зазначена ігнорована властивість була додана в редакції 8.3.5 з метою підтримки асинхронної роботи із зовнішніми компонентами, криптографією і розширеннями для роботи з файлами у веб-браузері Google Chrome. Зрозуміло, що до товстого клієнта це ніякого відношення не має, і тому “тихе” ігнорування цієї властивості просто виключило зайві перевірки використання синхронних методів при використанні конфігурації. До речі! Через те, що платформа впевнено рухається в бік вебу, з версії 8.3.8 розробники ввели певні обмеження на програмний код, який пов'язаний з логікою закриття форми або додатка, виконуваний у товстому і тонкому клієнтах. Обов'язково прочитайте нашу статтю, яка докладно висвітлює цей нюанс. Крім того, в курсі «Профессиональная разработка интерфейсов и форм в 1С:Предприятие 8.3», є глава, присвячена відмові від модальності, і ви можете почерпнути масу корисної та актуальної інформації з цієї теми. Колеги, існують дві речі які можна читати нескінченно: стрічку вконтакте і список змін у черговому релізі платформі, тому, давайте підбивати остаточні підсумки ;) У процесі розгляду прикладів, що дозволяють перейти від елементів синхронної моделі до асинхронної, ви, напевно, вже помітили, що в загальному випадку програмного коду стало більше. Чим більше коду, тим більше підвищується складність його подальшого супроводу і налагодження. Крім того, кількість коду ще більше збільшиться, якщо ми в процесі розробки будемо використовувати більшу кількість діалогів. Тому в процесі розробки прикладних рішень, орієнтованих на роботу у веб-клієнті, потрібно пам'ятати про ту парадигму роботи, яка використовується на цей момент у сучасних веб-додатках. Тому якщо у вашій конфігурації багато інтерактивних діалогів з користувачем, що видаються попереджень, то є сенс переглянути цю функціональність на користь якихось інших підходів в організації взаємодії з користувачем.
