Magento 2: Variablen von der Controller-Aktion an "View" übergeben

12

Wenn Sie in Magento 1 Daten aus Ihrer Controller-Aktion an die "Ansicht" übergeben möchten (dh einen Block in Ihrem Layout, können Sie)

  1. Fügen Sie der globalen Registrierung über einen Wert / ein Objekt hinzu Mage::register

  2. Rufen Sie direkt ein Blockobjekt ab und legen Sie nach der Ausführung die Dateneigenschaften für das abgerufene Blockobjekt fest loadLayout

  3. Rufen Sie Methoden für Blockobjekte in phtmlDateien auf und lassen Sie die Blockobjekte die Modell- / Datenbankschicht verwenden, um Daten zu lesen, die zuvor in der Controller-Aktion gespeichert wurden

Das Verwenden von Blockobjektmethoden zum Lesen aus der Datenbank scheint in Magento 2 weiterhin zu funktionieren - was für bestimmte Arten von Vorgängen geeignet ist. Jedoch,

  1. Es gibt keine globale Registrierung mehr in Magento 2 (oder?)

  2. Das Layout-System erstellt nun ein Seitenobjekt über eine Factory. Sie können Blockreferenzen nicht mehr wie in Magento 1 erfassen

Ist es in Magento 2 möglich, Daten direkt von einer Controller-Aktion an eine Ansicht weiterzuleiten? Oder ist dies ein zu direktes Muster für Magentos schöne neue Design Pattern ™ -Welt? Wenn dies ein zu direktes Muster ist, was ist zu tun, wenn einige berechnete Informationen in einer Vorlage angezeigt werden sollen, diese Informationen jedoch nicht in einem statusbehafteten System gespeichert werden sollen (dh, wir möchten sie nicht im System speichern) Datenbank)

Ich kann mich ein paar andere Möglichkeit , diese zusammen mich zu hacken - aber ich bin daran interessiert, wie Magento 2 will man es tun.

Hinweis : Mir ist klar, dass es mit so etwas möglich ist, eine Blockinstanz in einer Controller-Aktion abzurufen

$resultPage = $this->resultPageFactory->create();    
$block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js');        

var_dump(spl_object_hash($block));

Der Magento 2-Kerncode tut dies oft. Das im Controller-Objekt abgerufene Blockobjekt scheint jedoch ein anderes Objekt zu sein als es in einer phtmlVorlage über $thisoder verfügbar ist $block(das erstere ( $this) scheint das Objekt zu sein, das die Vorlage tatsächlich wiedergibt, während das letztere ( $block) zu sein scheint) eine Instanz vom Typ Magento Block).

#File: path/to/template.phtml
var_dump(spl_object_hash($block));
var_dump(spl_object_hash($this));

Ich sage "scheint zu sein", weil wenn ich Daten in der Controller-Aktionsmethode festlege, diese in der phtmlVorlage nicht verfügbar sind - und wenn ich die spl_object_hashobigen Ergebnisse vergleiche , erhalte ich drei verschiedene Hashes. Ich bin jedoch neu genug für all das, dass das oben Genannte ein anderer Fehler sein könnte, den ich gemacht habe. Wenn Sie also in der Lage waren, Daten für Blöcke festzulegen und sie in einer Vorlage abzurufen, würde ich gerne davon erfahren !

Alan Storm
quelle

Antworten:

17

In Bezug auf # 1 existiert die Registrierung noch, sehr ähnlich zu dem, was Sie von Magento 1 kennen. Sie wurde gerade verschoben. Sehen:\Magento\Framework\Registry

Fügen Sie es zu Ihrem Konstruktor über Dependency Injection, und dann können Sie Ihre gewohnte verwenden $registry->register($key, $value)und $registry->registry($key)Methoden zum Speichern / Zugangsdaten.

Ich würde empfehlen, im Namespace \ Magento \ Framework zu stöbern, wenn Sie dies noch nicht getan haben. Vieles, was zuvor über Mage oder App zugänglich war, ist immer noch da, nur aufgeteilt.

Was Best Practices anbelangt, kann ich das nicht beantworten, aber ich gehe davon aus, dass die Antwort darin besteht, so viel Logik wie möglich aus dem Controller herauszuhalten. Der Blick auf den Kern ist wahrscheinlich die beste Wahl. Siehe zum Beispiel die Bearbeitungsseite für Kundenadressen: Basic controller ; Umfangreicher Block - einschließlich Abrufen der Adress-ID und Laden, falls erforderlich. Das erledigen sie direkt im Block; Sie tun es nicht im Controller und geben es dann weiter.

Ryan Hoerr
quelle
2
Der Trick ist natürlich, zu wissen, welche Teile für den Kern betrachtet und welche ignoriert werden müssen :) Vielen Dank für die Hinweise, +1 für nützliche Informationen!
Alan Storm
1
+1 für den letzten Absatz. Wenn Sie einen berechneten Wert freigeben müssen, trennen Sie das Berechnungsverhalten von Objekten und rufen Sie es von Blöcken auf, die diesen Wert erfordern. Von der Registrierung wird abgeraten, da sie einen globalen, veränderlichen Status hat und Sie sich nie sicher sind, was Sie von dort erhalten werden. Von der direkten Adressierung von Aktionsblöcken wird ebenfalls abgeraten, da Sie nie sicher sind, ob ein Block auf einer Seite vorhanden ist (Layout kann ihn töten)
Anton Kril
@AntonKril wie wäre es mit Seitenrenderer-Helfern? CMS Page Helper, Product View Helper, sollen das Rendern von der HTTP-Anforderung trennen?
Ivan Chepurnyi
5

Sie sollten keine Variablen von der Controller-Aktion an die Ansicht übergeben. Verwenden Sie block für die Übergabe von Variablen an View (Template Engine).

KAndy
quelle
Warum? Wie können Sie get / post-Parameter vom Block zur Ansicht übergeben? Übergeben die meisten Logik sie nicht vom Controller an die Ansicht?
LucScu
Verwenden Sie Request Object in Blöcken. Wenn Sie das Abrufen von Daten vom Controller über die Registrierung blockieren, können Sie diese Blöcke nicht mit anderen Controllern verwenden. Es heißt Temporale Kopplung und ihre schlechten Praktiken
KAndy
Ich benutze $ block-> assign (), um die Parameter der Anfrage vom Controller an block zu übergeben. Ist es auch eine schlechte Praxis?
LucScu
Von der direkten Adressierung von Aktionsblöcken wird ebenfalls abgeraten, da Sie nie sicher sind, ob ein Block auf einer Seite vorhanden ist.
KAndy
In meinem Fall bin ich sicher, weil es ein benutzerdefiniertes Szenario ist, in dem Controller, Layout und Block nur von meinem Code gesteuert werden. Danke für eure Antworten!
LucScu