Jak dodać konkretny blok JS (i CSS) - sposób _w prawo?

9

Spędziłem więc dosłownie godziny godzin na googlowaniu, czytaniu, studiowaniu ect, ale nikt (nawet Alan Storm!) Nie powiedział mi tego. Wygląda na to, że cały internet jest zainteresowany dodaniem JS lub CSS do konkretnej strony Magento 2, ale to, czego szukam, to dodanie JS / CSS do określonego bloku .

Oto moje pytanie w skrócie:

Jaki jest najlepszy sposób dodania JS (i dodatkowo CSS) do określonego bloku , aby jeśli blok był obecny na stronie (*), JS / CSS jest ładowany, jeśli bloku nie ma, nie ma CSS / JS? ?

* Oznacza to, że gdziekolwiek można ustawić blok, na stronie / szablonie za pośrednictwem layout.xml, na stronie niestandardowej z mojego modułu, za pomocą metody toHtml bloku / strony lub, co najważniejsze, bloku osadzonego w WYSIWYG kategorii / opis produktu / Blok CMS / Strona CMS.

Przeczytałem DUŻO świetnych artykułów Alana (ponownie Kudos temu facetowi !!), nie wspominając o ryzach innych artykułów wokół tego , jednak mam wrażenie, że każdy chce dodać do strony, konkretnej strony, nie gdziekolwiek blok jest używany.

Wydaje mi się, że znam różne techniki, ale może coś mi tu brakuje, więc chciałbym uzyskać concensus od społeczności, a także być może trochę szyldu dla wszystkich czołowych graczy, aż do pełnych stosów deweloperów szukających podobne pytania i zastanawianie się nad opcjami tak jak ja.

Wcześniej w Magento 1 szukałem konstruktora bloków, pobierałem układ, uzyskiwałem odniesienie do głowy i wywoływałem tam addJs / addCss lub, jeśli to możliwe, korzystałem z metod w layout.xml. Oznaczałoby to, że JS został „dodany” do listy zasobów konstruktora bloków (zanim poziom kompozycji wyśle ​​blok główny). Ale teraz nie wydaje się to możliwe.

Przeczytałem o tym, jak przejść na temat dodawania JS / CSS (to nie jest proste „jak to zrobić?”, To jest bardziej zrozumiały „jaki jest prawidłowy / mag2 sposób ???”) i znam je techniki:

  • /view/[area]/layout/[default/page_id].xml technika, przy użyciu <head></head>elementów głównych
  • Dodanie bloku Head do mojego modułu, dołączonego do head.additional, z pewną logiką dotyczącą tego, czy mój blok jest załadowany
  • za pomocą obiektów \ Asset \ GroupedCollection i \ Asset \ Repository, aby wstrzyknąć od konstruktora strony / szablonu (nie wydaje się to jednak, że blokuje się blokami), potencjalnie kolejność ładowania?
  • Używanie RequireJS i stosowanie konfiguracji requJS do mojego modułu

Czy coś przeoczyłem?

Uważa się, że poprawnym sposobem byłoby użycie biblioteki RequireJS i atrybutów x-magento-init lub po prostu skryptu ze require("my_module", function(){ ... })składnią w skrypcie wbudowanym. Ale to wydaje mi się niezdarne? Musiałbym skonfigurować skrypty do ładowania skryptów, jestem zmuszony wstawić co najmniej część mojego JS, jednak wydaje się, że jest to najbardziej podejrzany sposób powiedzenia „oto mój blok, teraz potrzebuję trochę JS”, ​​poprzez włożenie tego do mojego phtml.

Chciałbym jednak naprawdę móc to zrobić za pośrednictwem PHP, jako programista zaplecza / stosu idealnie chciałbym zamknąć JS i (najlepiej) pozwolić zespołowi frontonu napisać to, jak chcą. W skrócie, zajmij się ładowaniem (Back End Dev to Frond End Dev "heres phtml, przesłonięcie w temacie, jeśli chcesz, podobnie heres pliku js, jego zależnych bibliotek i heres css dla bloku").

Sugeruje to __constructmetodę z wtryskiem zależności w systemie zasobów. Nie mogę jednak tego uruchomić, wydaje się to potwierdzone w szybkim artykule Alan Storms tutaj: Magento Quickies: Magento 2: Programowe dodawanie plików zasobów interfejsu użytkownika

Zwróć uwagę na podpis „Więc wszelkie myśli o tworzeniu bloków, które niosą ze sobą zasoby frontendu, są poza oknem”. ... porażka :(

Dziękuję wam za poświęcenie czasu na przeczytanie i przemyślenie . Czekam na Wasze odpowiedzi!

PS> Oczywiście jest to StackExchange, więc zaznaczę odpowiedź jako najlepszy kurs do tego, co próbuję osiągnąć (zablokuj ładowanie określonych zasobów), jednak postaram się również podać jako poprawkę na dole mojego postu wszelkie odpowiedzi które albo dodają do dyskusji, albo sugerują solidne rozwiązanie!

Cygnus Digital
źródło

Odpowiedzi:

5

Dla js powinno być łatwo, ponieważ używa Magento 2 require.js.
Oznacza to, że możesz dołączyć plik js w locie, gdy go potrzebujesz.

Blok musi być renderowany (w większości przypadków) za pomocą szablonu.
Musisz więc dodać to do szablonu:

<script type="text/javascript">
    require([
        "jquery",
        .... //any other js dependencies you have
        "Namespace_Module/js/filename_here"
    ], function(){
        //some js code here. 
        //if you don't need any additional js code just have an empty function
    });
</script>

Teraz utwórz plik js, w view/adminhtml|frontend/web/js/filename_here.jsktórym znajduje się cały kod js.

require.js będzie wiedział, jak odebrać plik na żądanie.

W przypadku plików css nie wiem, czy to możliwe.
Pliki css powinny przejść do headsekcji strony, ale na przykład, jeśli masz blok wewnątrz zawartości strony cms w ten sposób {{block class="..." template="..."}}, kiedy treść strony cms powinna zostać przetworzona, HTML do tego momentu jest już renderowany więc nie możesz dodać nic więcej do bloku głowy przez php. Możesz spróbować dodać go do szablonu w taki sposób, <style...ale nie tego chcesz (zakładam).

Marius
źródło
Dzięki Marius, badam trasę wymaganą jako jedną z możliwości wymienionych powyżej, ale dziękuję za ten przykładowy przykład! Zgadzam się jednak, że nie oferuje rozwiązania problemu CSS, jednak może to być wyciszenie ze względu na mniejszą kompilację Magento. Poza tym jest trochę abstrakcyjny, ale przypuszczam, że moglibyśmy użyć metody wymagaJS do załadowania naszego JS, co z kolei mogłoby dodać link do arkusza stylów do DOM, przynajmniej asynchroniczny !!!
Cygnus Digital
W rzeczywistości znajduję to na stronach wymagań, jak ładować CSS z RequireJS! : requjs.org/docs/faq-advanced.html#css
cygnus digital
@cygnusdigital. Miły. Więc problem rozwiązany :)
Marius
Cześć Marius, no cóż, tak i nie, to z pewnością dobry kandydat do rozwiązania, spełnia wymagania, więc dziękuję za Twój wkład, ale szukam dyskusji i alternatyw. Być może to tylko ja jestem dinozaurem, ale wydaje mi się, że bardziej liczy się ładowanie JS / CSS w konstruktorze, tj. „jeśli blok jest wbudowany / dołączony, dodaj to do głowy”. : DI zastanawiam się, czy można warunkowo dodać do bloku head.additional w locie. (tj. dodaj blok główny z mojego modułu do head.additional na etapie konstruktora bloków).
Cygnus Digital
możesz to zrobić za pomocą zwykłych bloków, które są dodawane za pomocą plików układu, ale jak wyjaśniłem, nie możesz tego zrobić dla bloków zawartych w zawartości strony za pomocą {{block}}dyrektyw, ponieważ sekcja nagłówka jest już renderowana po utworzeniu instancji klasy bloku.
Marius