Как добавить блок JS (и CSS) - _правильный_ способ?

9

Так что я буквально часами часами гуглял, читал, изучал т. Д., Но никто (даже Алан Шторм!) Не рассказал мне об этом. Кажется, весь интернет заинтересован в добавлении JS или CSS на определенную страницу Magento 2, но я ищу добавление JS / CSS в конкретный блок .

Итак, вот мой вопрос в двух словах:

Каков наилучший способ добавить JS (и дополнительно CSS) к определенному блоку , чтобы, если блок присутствует на странице (*), загружался JS / CSS, если блока там нет, CSS / JS нет? ?

* Это означает, что любой блок может быть установлен на странице / шаблоне с помощью layout.xml, на пользовательской странице моего модуля, с помощью метода toHtml блока / страницы или, что наиболее важно, блока, встроенного в WYSIWYG категории / описание продукта / CMS Block / CMS.

Я прочитал ОЧЕНЬ много замечательных статей Алана (еще раз слава этому парню !!), не говоря уже о множестве других статей, посвященных этому , однако я чувствую, что все хотят добавить на страницу, конкретную страницу, а не где-либо еще блок используется.

Я чувствую, что знаком с различными техниками, однако, возможно, я чего-то здесь упускаю, так что я хотел бы получить информацию от сообщества, а также, может быть, небольшую заметную заметку для всех фронтальных эндов, готовых к полному стеку разработчиков, ищущих похожие вопросы и обдумывать варианты как я.

Ранее в Magento 1 я смотрел на конструктор блоков, получал макет, получал ссылку на заголовок и вызывал там addJs / addCss или, если возможно, использовал методы в layout.xml. Это означало бы, что JS был «добавлен» в список ресурсов конструктора блоков (до того, как уровень темы выведет блок заголовка). Но сейчас это кажется невозможным.

Я прочитал о том, как идти о добавлении JS / CSS (это не просто «как я ???», это более краткий «как правильно / mag2 путь ???») и знаком с этим методы:

  • /view/[area]/layout/[default/page_id].xml метод с использованием <head></head>корневых элементов
  • Добавление блока Head в мой модуль, добавленный в head.additional, с некоторой логикой относительно того, загружен ли мой блок
  • используя объекты \ Asset \ GroupedCollection и \ Asset \ Repository для внедрения из custructor страницы / шаблона (хотя это не похоже на работу с блоками), потенциально, порядок загрузки ??
  • Использование RequireJS и применение конфигурации requireJS к моему модулю

Я что-то пропустил?

Кто-то считает, что правильным способом было бы использовать библиотеку RequireJS и либо атрибуты x-magento-init, либо просто скрипт с require("my_module", function(){ ... })синтаксисом во встроенном скрипте. Но это кажется клунки для меня? Я должен был бы настроить сценарии для загрузки сценариев, я вынужден встроить по крайней мере некоторые из моих JS, однако это кажется наиболее разумным способом сказать «вот мой блок, теперь мне нужен JS», вставив это в мой phtml.

Однако мне бы очень хотелось иметь возможность делать это через PHP, поскольку я программист бэкэнда / стека, в идеале я хотел бы инкапсулировать JS и (в идеале) позволить моей команде переднего плана написать это так, как они этого хотят. Короче говоря, позаботьтесь о загрузке (Back End Dev to Frond End Dev «здесь, если хотите, переписываете phtml, переопределяете тему, также здесь - файл js, его зависимые библиотеки и css для блока»).

Это предполагает __constructметод с введенными зависимостями в системе активов. Однако я не могу заставить это работать, это, кажется, подтверждается в быстрой статье Alan Storms здесь: Magento Quickies: Magento 2: Добавление файлов активов внешнего интерфейса программно

Обратите внимание на знак «Таким образом, любые мысли о создании блоков, которые несут с собой свои внешние ресурсы, находятся вне окна». ... облом :(

Спасибо, ребята, что нашли время, чтобы прочитать и рассмотреть . Я с нетерпением жду ваших ответов!

PS> Очевидно, что это StackExchange, поэтому я отмечу ответ как лучший курс для того, чего я пытаюсь достичь (заблокировать загрузку определенных ресурсов), однако я постараюсь также перечислить в качестве ссылок в нижней части моего поста все ответы что либо добавить к обсуждению, либо предложить солидное решение!

Cygnus Digital
источник

Ответы:

5

Для js это должно быть легко, потому что magento 2 использует require.js.
Так что это означает, что вы можете включать JS на лету, когда вам это нужно.

Блок должен быть представлен (в большинстве случаев) с помощью шаблона.
Так что вам нужно добавить это в свой шаблон:

<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>

Теперь создайте свой js-файл, в view/adminhtml|frontend/web/js/filename_here.jsкотором присутствует весь ваш js-код.

require.js будет знать, как забрать ваш файл, когда он будет запрошен.

Для файлов CSS я не знаю, возможно ли это.
Файлы css должны идти в headраздел страницы, но, например, если у вас есть блок внутри содержимого страницы cms, как это {{block class="..." template="..."}}, когда содержимое страницы cms должно быть обработано, html до этого момента уже отображается так что вы не можете добавить что-либо еще в головной блок через php. Вы можете попробовать добавить его в шаблон, например, <style...но это не то, что вы хотите (я предполагаю).

Мариус
источник
Спасибо Мариус, я рассматриваю маршрут requireJS как одну из возможностей, которые я перечислил выше, но спасибо за удачный пример! Я согласен, однако, что он не предлагает решения проблемы CSS, однако это может быть немой момент из-за действия компилятора Less в Magento. Кроме того, это abit abstract, но я полагаю, что мы могли бы использовать requireJS для загрузки нашего JS, который, в свою очередь, мог бы добавить ссылку на таблицу стилей в DOM, по крайней мере, асинхронно !!!
Cygnus Digital
Фактически, я нахожу это на страницах requirejs, как загрузить CSS с RequireJS! : requirejs.org/docs/faq-advanced.html#css
cygnus digital
@cygnusdigital. Ницца. Так что проблема решена :)
Мариус
Привет Мариус, ну да и нет, конечно, это хороший кандидат на решение, оно соответствует требованиям, поэтому я благодарю вас за ваш вклад, но я ищу обсуждение и альтернативы. Возможно, это просто я динозавр, но я чувствую, что лучше иметь загрузку JS / CSS внутри конструктора, т.е. «если блок построен / включен, добавьте это в голову». : D Мне интересно, можно ли условно добавить блок head.addition на лету. (т.е. добавить блок head из моего модуля в head.additional на этапе конструктора блока).
Cygnus Digital
Вы можете сделать это с обычными блоками, которые добавляются через файлы макетов, но, как я объяснил, вы не можете сделать это для блоков, включенных в содержимое страницы с помощью {{block}}директив, потому что раздел head уже визуализируется, когда создается экземпляр класса блока.
Мариус