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/
Zastosowanie W artykule omawiany jest asynchroniczny model budowania logiki biznesowej, dodany do platformy „1C:Przedsiębiorstwo” edycji 8.3. Przedstawione informacje są aktualne dla obecnych wydań platformy. Rezygnacja z użycia okien modalnych w platformie 1C:Przedsiębiorstwo 8.3 Przy tworzeniu konfiguracji na platformie 1C:Przedsiębiorstwo 8 okresowo pojawia się potrzeba wstrzymania działania programu do momentu, w którym użytkownik podejmie jakąś decyzję lub wykona jakieś działania. Na przykład, po kliknięciu przycisku wypełniania części tabelarycznej, należy zapytać użytkownika, czy należy wyczyścić część tabelaryczną, aby uniknąć utraty wcześniej wprowadzonych danych. Takie zachowanie może zapewnić następujący kod: &NaKliencie Procedura WypełnijTowary(Komenda) Odpowiedz = Pytanie(„Część tabelaryczna zostanie wyczyszczona. Kontynuować?”, TrybDialoguPytania.TakNie); Jeśli Odpowiedz = KodZwrotuDialogu.Tak To //algorytm wypełniania KoniecJeśli; KoniecProcedury W wyniku działania tego fragmentu kodu nastąpi wstrzymanie wykonania kodu programowego, na ekranie wyświetlane jest pytanie, interfejs aplikacji poza dialogiem z pytaniem staje się niedostępny, system oczekuje na podjęcie decyzji przez użytkownika, wykonanie kodu wznowi się dopiero po udzieleniu odpowiedzi na pytanie. Do wstrzymania wykonania kodu i zablokowania interfejsu prowadzi również otwieranie okien modalnych za pomocą wywołania metody OtwórzModalnie(). Przy pracy z konfiguracją w trybie klienta sieciowego przez przeglądarkę w tym przypadku zostanie otwarte nowe okno – wyskakujące okno, które zablokuje nie tylko bieżącą kartę, ale cały interfejs przeglądarki, w tym pozostałe otwarte okna i karty. Okna wyskakujące w Internecie często są wykorzystywane do złośliwego rozpowszechniania niechcianej reklamy, dlatego przeglądarki zawierają funkcje blokowania okien wyskakujących. W takim przypadku, aby pracować z konfiguracjami 1C:Przedsiębiorstwo 8 przez przeglądarkę, należy zablokować blokowanie okien wyskakujących. Problemy pojawiają się również przy pracy na urządzeniach mobilnych. Na przykład, okna modalne nie są obsługiwane na iPadzie. Aby rozwiązać wymienione problemy, należy używać okien blokujących zamiast modalnych. Dla użytkownika wizualnie wszystko wygląda tak samo: okno blokuje interfejs klienta sieciowego. Jednak okno blokujące jest „rysowane” na wierzchu głównego okna i blokowana jest tylko bieżąca karta przeglądarki, w której otwarta jest konfiguracja, pozwalając na przełączanie się na inne karty, ponieważ okna modalne przeglądarki nie są w tym przypadku używane. W ten sposób okna wyskakujące w przeglądarce nie są otwierane i zapewniona jest praca przez klienta sieciowego na urządzeniach mobilnych. W elemencie głównym konfiguracji istnieje właściwość „Tryb używania modalności”, która określa, czy w konfiguracji można otwierać okna modalne. Jeśli wybrano opcję „Używać”, okna modalne można otwierać. Jeśli wybrano opcję „Nie używać”, okna modalne są niedopuszczalne. Przy próbie wywołania metody otwierającej okno modalne system wyświetla komunikat o błędzie: Przy takiej wartości właściwości „Tryb używania modalności” dopuszczalne są tylko okna blokujące. Jeśli wybrano opcję „Używać z ostrzeżeniami”, to przy otwieraniu okien modalnych w oknie komunikatów wyświetlany jest tekst: Taki tryb pracy może być używany jako pośredni podczas przerabiania konfiguracji w celu rezygnacji z używania okien modalnych. Główna różnica między oknami blokującymi a modalnymi polega na tym, że otwarcie okna blokującego nie powoduje wstrzymania wykonania kodu. Dlatego programiści będą musieli przepisać kod programowy używający okien modalnych, uwzględniając tę cechę. Kod należy podzielić na dwie części: otwarcie okna blokującego; obsługa wyboru użytkownika. Fragment kodu podany na początku artykułu należy przepisać w następujący sposób: &NaKliencie Procedura WypełnijTowary(Komenda) Powiadomienie = Nowy OpisPowiadomienia(„WypełnijTowaryPytanieZakończenie”, TenObiekt); TekstPytania = „Część tabelaryczna zostanie wyczyszczona. Kontynuować?”; PokażPytanie(Powiadomienie, TekstPytania, TrybDialoguPytania.TakNie); KoniecProcedury &NaKliencie Procedura WypełnijTowaryPytanieZakończenie(Wynik, DodatkoweParametry) Eksport Jeśli Wynik = KodZwrotuDialogu.Tak To //algorytm wypełniania KoniecJeśli; KoniecProcedury Po wykonaniu procedury PokażPytanie() system nie zatrzymuje się, oczekując na odpowiedź użytkownika, wykonanie kodu kontynuuje się. Użytkownik będzie mógł dokonać wyboru dopiero po zakończeniu działania całej procedury. W tym przypadku zostanie wywołana eksportowa procedura WypełnijTowaryPytanieZakończenie(). Jej nazwę przekazaliśmy w konstruktorze obiektu OpisPowiadomienia. Procedura, która zostanie wywołana po dokonaniu wyboru, może znajdować się w module formularza, module komendy, ogólnym nieglobalnym module. W rozpatrywanym przykładzie wywoływana procedura znajduje się w module sterowanego formularza, dlatego przekazaliśmy w parametrze TenObiekt. Rozważmy wywołanie procedury znajdującej się w ogólnym module. W tym celu dodajemy nowy ogólny moduł ObsługaPowiadomień, ustawiamy dla niego flagę „Klient (aplikacja sterowana)”, a znacznik „Globalny” nie jest ustawiany. Umieszczamy w tym module procedurę WypełnijTowaryPytanieZakończenie(). Wtedy obsługa komendy wypełniania będzie wyglądać tak: &NaKliencie Procedura WypełnijTowary(Komenda) Powiadomienie = Nowy OpisPowiadomienia(„WypełnijTowaryPytanieZakończenie”, ObsługaPowiadomień); TekstPytania = „Część tabelaryczna zostanie wyczyszczona. Kontynuować?”; PokażPytanie(Powiadomienie, TekstPytania, TrybDialoguPytania.TakNie); KoniecProcedury Po wywołaniu dowolnej metody otwierającej okno blokujące, procedura powinna się zakończyć, a kod wykonywany dalej należy umieszczać w procedurze, która zostanie wywołana po zamknięciu okna. W celu przekazania kontekstu (danych pomocniczych, pewnych parametrów, wartości zmiennych) z procedury otwierającej okno modalne do procedury wywoływanej przy jego zamknięciu, przewidziany jest trzeci opcjonalny parametr konstruktora obiektu OpisPowiadomienia – DodatkoweParametry. Ten obiekt (dowolnego typu) zostanie przekazany do procedury opisanej w OpisPowiadomienia jako ostatni parametr. Na przykładzie rozpatrywanego powyżej fragmentu kodu można to zrobić tak: &NaKliencie Procedura WypełnijTowary(Komenda) Parametr1 = 0; Parametr2 = 0; ListaParametrów = Nowy Struktura(„Parametr1, Parametr2”, Parametr1, Parametr2); Powiadomienie = Nowy OpisPowiadomienia(„WypełnijTowaryPytanieZakończenie”, TenObiekt, ListaParametrów); PokażPytanie(Powiadomienie, „Część tabelaryczna zostanie wyczyszczona. Kontynuować?”, TrybDialoguPytania.TakNie); KoniecProcedury &NaKliencie Procedura WypełnijTowaryPytanieZakończenie(Wynik, DodatkoweParametry) Eksport Jeśli Wynik = KodZwrotuDialogu.Tak To //analizujemy DodatkoweParametry.Parametr1 //analizujemy DodatkoweParametry.Parametr2 KoniecJeśli; KoniecProcedury Jeśli trzeba przekazać tylko jedną wartość, to struktury nie trzeba używać, a tę wartość należy przypisać parametrowi DodatkoweParametry konstruktora obiektu OpisPowiadomienia. Rozważmy kilka przykładów pracy z oknami blokującymi. Zadanie 1. Otwarcie innego formularza Z formularza dokumentu po kliknięciu przycisku „Otwórz parametry” należy otworzyć formularz, na którym znajdują się dwa pola wyboru Parametr1 i Parametr2, które musi ustawić użytkownik. Po zamknięciu formularza wyświetlić w wierszu komunikatów wartości parametrów. Tworzymy ogólny formularz „FormularzParametrów”, na którym umieszczamy atrybuty Parametr1 i Parametr2, a także komendę ZamknijFormularz: Obsługa komendy wygląda następująco: Obsługa komendy wygląda następująco: &NaKliencie Procedura ZamknijFormularz(Komenda) ListaParametrów = Nowy Struktura(„Parametr1, Parametr2”, Parametr1, Parametr2); Zamknij(ListaParametrów); KoniecProcedury Dla formularza właściwość TrybOtwieraniaOkna ustawiamy na „Blokuj cały interfejs”: Na formularzu dokumentu umieszczamy komendę OtwórzParametry, której obsługa opisana jest w następujący sposób: &NaKliencie Procedura OtwórzParametry(Komenda) Powiadomienie = Nowy OpisPowiadomienia(„OtwórzParametryZakończenie”, TenObiekt); OtwórzFormularz(„OgólnyFormularz.FormularzParametrów”, , , , , , Powiadomienie); KoniecProcedury &NaKliencie Procedura OtwórzParametryZakończenie(Wynik, DodatkoweParametry) Eksport Jeśli TypWartości(Wynik) = Typ(„Struktura”) To Dla każdego KluczWartosc z Wynik Cykl Komunikat = Nowy KomunikatUżytkownika; Komunikat.Tekst = „Klucz: „”” + KluczWartosc.Klucz + „””, wartość = ” + KluczWartosc.Wartość; Komunikat.Poinformuj(); KoniecCyklu; KoniecJeśli; KoniecProcedury W trybie użytkownika, uruchamiając konfigurację pod klientem sieciowym, otrzymujemy takie wyniki działania: Aby powiększyć, kliknij obraz. Tryb otwierania okna można również podawać w ostatnim parametrze procedury OtwórzFormularz. &NaKliencie Procedura OtwórzParametry(Komenda) Powiadomienie = Nowy OpisPowiadomienia(„OtwórzParametryZakończenie”, TenObiekt); OtwórzFormularz(„OgólnyFormularz.FormularzParametrów”, , , , , , Powiadomienie, TrybOtwieraniaFormularza.BlokujCałyInterfejs); KoniecProcedury Zadanie 2. Pytanie przy zamykaniu formularza Przy zamykaniu okna przetwarzania zadawać użytkownikowi pytanie, czy na pewno chce zamknąć okno. To zadanie można rozwiązać przy pomocy następującego kodu, znajdującego się w module formularza przetwarzania: &NaKliencie Zmienna CzyZamykaćFormularz; &NaKliencie Procedura PrzedZamknięciem(Odmowa, StandardowaObsługa) Jeśli NIE CzyZamykaćFormularz = Prawda To Odmowa = Prawda; Powiadomienie = Nowy OpisPowiadomienia(„PrzedZamknięciemZakończenie”, TenObiekt); PokażPytanie(Powiadomienie, „Czy na pewno chcesz zamknąć okno?”, TrybDialoguPytania.TakNie); KoniecJeśli; KoniecProcedury &NaKliencie Procedura PrzedZamknięciemZakończenie(Wynik, DodatkoweParametry) Eksport Jeśli Wynik = KodZwrotuDialogu.Tak To CzyZamykaćFormularz = Prawda; Zamknij(); Inaczej CzyZamykaćFormularz = Nieokreślono; KoniecJeśli; KoniecProcedury W procedurze PrzedZamknięciem formularza użytkownikowi zadawane jest pytanie, flaga Odmowa ustawiana jest na Prawda, zamykanie formularza jest anulowane. Po potwierdzającej odpowiedzi na pytanie zmienna CzyZamykaćFormularz ustawiana jest na Prawda, formularz zamykany jest ponownie. Zadanie 3. Wprowadzenie wartości liczbowej Po kliknięciu przycisku na formularzu przetwarzania otwierać standardowy dialog wprowadzania liczby. W tym celu należy skorzystać z metody PokażWprowadźLiczbe() zamiast WprowadźLiczbe(), która otwiera okno blokujące zamiast modalnego. &NaKliencie Procedura WprowadźLiczbe(Komenda) Powiadomienie = Nowy OpisPowiadomienia(„WprowadźLiczbeZakończenie”, TenObiekt); PokażWprowadźLiczbe(Powiadomienie, 0, „Wprowadź ilość”, 15, 3); KoniecProcedury &NaKliencie Procedura WprowadźLiczbeZakończenie(Wynik, DodatkoweParametry) Eksport Jeśli NIE Wynik = Nieokreślono To Komunikat = Nowy KomunikatUżytkownika; Komunikat.Tekst = „Wprowadziłeś ilość ” + Wynik; Komunikat.Poinformuj(); KoniecJeśli; KoniecProcedury Po zamknięciu okna wprowadzania liczby zostanie wywołana procedura, do pierwszego parametru której zostanie przekazana wprowadzona liczba lub wartość Nieokreślono, jeśli użytkownik odmówił wprowadzania. Zadanie 4. Wybór koloru Po kliknięciu przycisku na formularzu przetwarzania przy pomocy standardowego dialogu wyboru koloru użytkownik wskazuje wymagany kolor. Ten kolor należy ustawić dla tła klikniętego przycisku. Dodajemy na formularz komendę WybierzKolor z następującą obsługą: &NaKliencie Procedura WybierzKolor(Komenda) DialogWyboruKoloru = Nowy DialogWyboruKoloru; Powiadomienie = Nowy OpisPowiadomienia(„WybierzKolorZakończenie”, TenObiekt); DialogWyboruKoloru.Pokaż(Powiadomienie); KoniecProcedury &NaKliencie Procedura WybierzKolorZakończenie(Wynik, DodatkoweParametry) Eksport Jeśli NIE Wynik = Nieokreślono To Elementy.WybierzKolor.KolorTła = Wynik; KoniecJeśli; KoniecProcedury Dla obiektów DialogWyboruKoloru (oraz DialogEdycjiStandardowegoOkresu, KonstruktorFormatuTekstu, DialogHarmonogramuZadaniaPlanowego, DialogWyboruCzcionki) metoda Pokaż() otwiera okno blokujące. Po zamknięciu okna zostanie wywołana procedura, do pierwszego parametru której zostanie przekazana wybrana wartość (kolor, czcionka itp.) lub wartość Nieokreślono, jeśli użytkownik odmówił wyboru. Należy zwrócić uwagę, że obiekt DialogWyboruPliku nie ma metody Pokaż() w przeciwieństwie do dialogów wyboru koloru lub czcionki, ponieważ implementacja tych dialogów jest znacznie różna. W celu użycia dialogu wyboru pliku na kliencie sieciowym należy wcześniej podłączyć rozszerzenie pracy z plikami. Dialogi realizowane przez rozszerzenie pracy z plikami nie tworzą takich problemów w działaniu, jak okna modalne przeglądarek, dlatego nie zrealizowano otwierania okien blokujących dla obiektu DialogWyboruPliku. Podsumowując, należy zauważyć, że począwszy od wydania 8.3.10 w kliencie sieciowym zaprzestano obsługi okien modalnych. W tym przypadku, jeśli w konfiguracji następuje wywołanie metody modalnej, generowany jest wyjątek. Ponadto w kliencie sieciowym zaprzestano obsługi trybu interfejsu W osobnych oknach. Co więcej, zarówno w cienkim, jak i w kliencie sieciowym nie można już otwierać formularza w osobnym oknie (przy pracy w trybie interfejsu W kartach). Takie radykalne kroki pozwoliły zrezygnować z trybu interfejsu, który już nie jest obsługiwany przez wszystkie nowoczesne przeglądarki. Jaki praktyczny wniosek można wyciągnąć z tej informacji? Wniosek jest dość prosty – jeśli z jakiegoś powodu w Twojej konfiguracji nadal istnieją wywołania modalne, to w tych miejscach w kliencie sieciowym będzie wyświetlane okno z komunikatem o błędzie. Chciałbym ostrzec przed próbami „znalezienia w sieci” jakiegoś szybkiego rozwiązania tego problemu, ponieważ większość porad sprowadza się do takiej recepty: w konfiguratorze na poziomie konfiguracji we właściwości „Tryb używania modalności” ustawić wartość „Używać”. Oczywiście, w tym momencie nie będzie to działać tylko dlatego, że same nowoczesne przeglądarki już nie obsługują wywołań modalnych. I masz tylko dwie drogi, w jaki sposób rozwiązać powyższy problem: Zaktualizuj platformę do wydania 8.3.10+ (8.3.11), ustaw właściwość konfiguracji „Tryb zgodności” na „Nie używać” i przepisz fragmenty kodu używające metod modalnych na asynchroniczny model budowania logiki biznesowej Zalecać Twoim klientom korzystanie z przestarzałych przeglądarek, w których wywołania modalne były jeszcze obsługiwane (Mozilla Firefox wersji 37 i poniżej, Chrome poniżej wersji 37 itd.). Co więcej, począwszy od wydania 8.3.11, nie są już obsługiwane przeglądarki sieciowe Microsoft Internet Explorer wersji 8 i 9. Z przeglądarkami sieciowymi w kontekście modalności uporaliśmy się, teraz nadszedł czas, aby wyjaśnić sytuację z pozostałymi klientami. Począwszy od wersji 8.3.5 właściwość „Tryb używania modalności” w cienkim i grubym kliencie jest uwzględniana tylko wtedy, gdy podany jest parametr wiersza poleceń /EnableCheckModal. Ten parametr jest automatycznie wstawiany do wiersza poleceń tylko przy uruchamianiu aplikacji z konfiguratora. Jeśli ten parametr nie jest podany, to generowanie wyjątków nie zachodzi i odpowiednie ostrzeżenia nie są wyświetlane. Tzn. w praktyce w przypadku użycia grubego i cienkiego klienta nie obserwuje się żadnej radykalnej zmiany w działaniu przy użyciu trybu modalności – wywołania modalne będą działać tak samo, jak działały wcześniej, nie wyświetlając żadnych ostrzeżeń, jak w kliencie sieciowym. Aby postawić wszystkie kropki nad „i”, zauważmy, że począwszy od edycji 8.3.9 w grubym kliencie ignorowana jest właściwość konfiguracji „Tryb używania synchronicznych wywołań rozszerzeń platformy i komponentów zewnętrznych”, przy czym odpowiednie metody synchroniczne działają bez generowania wyjątków i wyświetlania ostrzeżeń. Powyższa ignorowana właściwość została dodana w edycji 8.3.5 w celu obsługi asynchronicznej pracy z komponentami zewnętrznymi, kryptografią i rozszerzeniami do pracy z plikami w przeglądarce internetowej Google Chrome. Jasne jest, że nie ma to żadnego związku z grubym klientem, dlatego „ciche” ignorowanie tej właściwości po prostu wykluczyło dodatkowe sprawdzanie używania metod synchronicznych przy użyciu konfiguracji. Co ciekawe! Z powodu tego, że platforma pewnie zmierza w stronę sieci, od wersji 8.3.8 programiści wprowadzili pewne ograniczenia na kod programowy, który jest związany z logiką zamykania formularza lub aplikacji, wykonywanym w grubym i cienkim kliencie. Koniecznie przeczytaj nasz artykuł, szczegółowo omawiający ten niuans. Ponadto, w kursie „Profesjonalne tworzenie interfejsów i formularzy w 1C:Przedsiębiorstwo 8.3” znajduje się rozdział poświęcony rezygnacji z modalności, i możesz czerpać masę przydatnych i aktualnych informacji na ten temat. Koledzy, istnieją dwie rzeczy, które można czytać w nieskończoność: wstawkę w kontakcie i listę zmian w kolejnym wydaniu platformy, więc podsumujmy ostateczne wnioski ;) W trakcie rozpatrywania przykładów, pozwalających przejść od elementów synchronicznego modelu do asynchronicznego, zauważyłeś pewnie, że ogólnie kodu programowego stało się więcej. Im więcej kodu, tym bardziej wzrasta złożoność jego dalszego utrzymania i debugowania. Co więcej, ilość kodu jeszcze bardziej wzrośnie, jeśli w trakcie tworzenia będziemy używać większej liczby dialogów. Dlatego w trakcie tworzenia rozwiązań aplikacyjnych, nastawionych na pracę w kliencie sieciowym, należy pamiętać o paradymacie pracy, który jest używany obecnie w nowoczesnych aplikacjach sieciowych. Dlatego jeśli w Twojej konfiguracji jest dużo interaktywnych dialogów z użytkownikiem, wyświetlanych ostrzeżeń, to ma sens przemyśleć tę funkcjonalność na rzecz innych podejść w organizacji interakcji z użytkownikiem.
