Wie füge ich blockspezifisches JS (und CSS) hinzu?

9

Ich habe buchstäblich Stunden damit verbracht, zu googeln, zu lesen, ect zu studieren, aber niemand (nicht einmal Alan Storm!) Hat mir das erklärt. Es scheint, dass das gesamte Internet daran interessiert ist, JS oder CSS zu einer bestimmten Seite von Magento 2 hinzuzufügen, aber ich suche nach dem Hinzufügen von JS / CSS zu einem bestimmten Block .

Also, hier ist meine Frage auf den Punkt gebracht:

Was ist der beste Weg, um JS (und zusätzlich CSS) zu einem bestimmten Block hinzuzufügen , sodass, wenn der Block auf der Seite (*) vorhanden ist, das JS / CSS geladen wird, wenn der Block nicht vorhanden ist, kein CSS / JS? ?

* Dies bedeutet, dass jeder Block auf einer Seite / Vorlage über layout.xml, auf einer benutzerdefinierten Seite aus meinem Modul, über die toHtml-Methode eines Blocks / einer Seite oder vor allem eines in ein WYSIWYG einer Kategorie eingebetteten Blocks eingerichtet werden kann / Produktbeschreibung / CMS Block / CMS Seite.

Ich habe VIELE von Alans großartigen Artikeln gelesen (nochmals ein großes Lob an diesen Kerl !!), ganz zu schweigen von den Unmengen anderer Artikel , aber ich habe das Gefühl, dass jeder einer Seite, einer bestimmten Seite, hinzufügen möchte, nicht wo immer die Block wird verwendet.

Ich fühle mich mit den verschiedenen Techniken vertraut, aber hier fehlt mir möglicherweise etwas, daher möchte ich einen Konsens aus der Community sowie einen kleinen Wegweiser für alle Front-Ender, die Entwickler mit vollem Stapel suchen ähnliche Fragen und Nachdenken über die Optionen wie ich.

Zuvor habe ich in Magento 1 nach dem Blockkonstruktor gesucht, das Layout abgerufen, die Kopfreferenz abgerufen und dort addJs / addCss aufgerufen oder wenn möglich die Methoden in der Datei layout.xml verwendet. Dies würde bedeuten, dass der JS zur Ressourcenliste im Blockkonstruktor "hinzugefügt" wurde (bevor die Themenebene den Kopfblock ausgeben würde). Aber das scheint jetzt nicht möglich zu sein.

Ich habe gelesen, wie man JS / CSS hinzufügt (dies ist kein einfaches "Wie mache ich ???", dies ist ein präziseres "Was ist der richtige / mag2-Weg ???") und bin mit diesen vertraut Techniken:

  • /view/[area]/layout/[default/page_id].xml Technik, die unter Verwendung von <head></head>Stammelementen
  • Hinzufügen eines Head- Blocks zu meinem Modul, der in head.additional angehängt ist, mit einer Art Logik, ob mein Block geladen ist
  • Verwenden Sie die Objekte \ Asset \ GroupedCollection und \ Asset \ Repository, um sie vom Custructor einer Seite / Vorlage einzufügen (dies scheint jedoch nicht mit Blöcken zu funktionieren), möglicherweise die Reihenfolge des Ladens?
  • Verwenden von RequireJS und Anwenden einer requireJS-Konfiguration auf mein Modul

Habe ich etwas verpasst?

Man glaubt, der richtige Weg wäre, die RequireJS-Bibliothek und entweder x-magento-init-Attribute oder nur ein Skript mit einer require("my_module", function(){ ... })Syntax in einem Inline-Skript zu verwenden. Aber das scheint mir klunky? Ich müsste Skripte einrichten, um Skripte zu laden, bin gezwungen, zumindest einige meiner JS zu inline, aber es scheint die naheliegendste Art zu sein, zu sagen: "Hier ist mein Block, jetzt benötige ich JS", indem ich dies in mein HTML einfüge.

Ich würde dies jedoch gerne über PHP tun können, da ich als Backend / Stack-Programmierer die JS idealerweise wegkapseln und (im Idealfall) meinem Front-End-Team erlauben würde, dies so zu schreiben, wie sie es wollen. Kurz gesagt, kümmern Sie sich um das Laden (Back End Dev zu Frond End Dev "hier ist das HTML, überschreiben Sie das Thema, wenn Sie möchten, hier ist auch die js-Datei, ihre abhängigen Bibliotheken und hier ist das CSS für den Block").

Dies legt die __constructMethode mit injizierten Abhängigkeiten vom Assets-System nahe. Ich kann dies jedoch nicht zum Laufen bringen. Dies scheint in Alan Storms Kurzartikel hier bestätigt zu sein: Magento Quickies: Magento 2: Programmgesteuertes Hinzufügen von Frontend-Asset-Dateien

Beachten Sie die Abmeldung "Alle Gedanken daran, Blöcke zu erstellen, die ihre Frontend-Assets mit sich führen, sind aus dem Fenster." ... Mist :(

Vielen Dank, dass Sie sich die Zeit zum Lesen und Überlegen genommen haben . Ich freue mich auf Ihre Antworten!

PS> Offensichtlich ist dies StackExchange, daher werde ich die Antwort als den besten Kurs für das markieren, was ich erreichen möchte (blockspezifisches Laden von Ressourcen). Ich werde mich jedoch bemühen, alle Antworten am Ende meines Beitrags als Referenzen aufzulisten das entweder zur Diskussion beitragen oder eine solide Lösung vorschlagen!

cygnus digital
quelle

Antworten:

5

Für js sollte es einfach sein, da Magento 2 verwendet require.js.
Dies bedeutet, dass Sie ein js on the fly einfügen können, wenn Sie es benötigen.

Ein Block muss (in den meisten Fällen) von einer Vorlage gerendert werden.
Sie müssen dies also in Ihre Vorlage einfügen:

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

Erstellen Sie nun Ihre js-Datei, view/adminhtml|frontend/web/js/filename_here.jsin der Ihr gesamter js-Code vorhanden ist.

require.js wird wissen, wie Sie Ihre Datei abholen, wenn es angefordert wird.

Für CSS-Dateien weiß ich nicht, ob es möglich ist.
Die CSS-Dateien sollten in den headAbschnitt der Seite verschoben werden. Wenn Sie beispielsweise Ihren Block im Inhalt einer solchen CMS-Seite haben {{block class="..." template="..."}}und der Inhalt der CMS-Seite verarbeitet werden soll, wird der HTML-Code bis zu diesem Punkt bereits gerendert Sie können dem Headblock also über PHP nichts anderes hinzufügen. Sie können versuchen, es wie folgt in die Vorlage einzufügen, <style...aber das ist nicht das, was Sie wollen (nehme ich an).

Marius
quelle
Danke Marius, ich erkunde die requireJS-Route als eine der Möglichkeiten, die ich oben aufgeführt habe, aber danke für das gute Beispiel! Ich bin damit einverstanden, dass es jedoch keine Lösung für das CSS-Problem bietet. Dies kann jedoch aufgrund von Magentos Less-Compiler-Effekt ein stummer Punkt sein. Es ist auch ein bisschen abstrakt, aber ich nehme an, wir könnten requireJS verwenden, um unser JS zu laden, was wiederum einen Link zum Stylesheet zum DOM hinzufügen könnte, zumindest asynchron !!!
Cygnus Digital
Tatsächlich finde ich dies auf den requirejs-Seiten, wie man CSS mit RequireJS lädt! : requirejs.org/docs/faq-advanced.html#css
Cygnus Digital
@cygnusdigital. Nett. Also Problem gelöst :)
Marius
Hallo Marius, ja und nein, es ist mit Sicherheit ein guter Kandidat für die Lösung. Es entspricht den Anforderungen. Ich danke Ihnen für Ihre Beiträge, suche aber nach Diskussionen und Alternativen. Vielleicht bin ich nur ein Dinosaurier, aber ich finde es sicherer, dass JS / CSS in einem Konstruktor geladen wird, d. H. "Wenn der Block gebaut / enthalten ist, fügen Sie diesen dem Kopf hinzu." : DI frage mich, ob es möglich ist, den Kopf bedingt zu ergänzen. Zusätzlicher Block im laufenden Betrieb. (dh fügen Sie im Blockkonstruktor-Stadium einen Kopfblock aus meinem Modul zu head.additional hinzu).
Cygnus Digital
Sie können dies mit regulären Blöcken tun, die über Layoutdateien hinzugefügt werden. Wie ich bereits erklärt habe, können Sie dies jedoch nicht für Blöcke tun, die über {{block}}Direktiven im Seiteninhalt enthalten sind , da der Kopfabschnitt bereits gerendert wird, wenn die Blockklasse instanziiert wird.
Marius