Magento 2: Przekazywanie zmiennych z działania kontrolera do „Widoku”

12

W Magento 1, jeśli chcesz przekazać dane z akcji Kontrolera do „Widoku” (tzn. Bloku w twoim układzie, możesz)

  1. Dodaj wartość / obiekt do rejestru globalnego za pomocą Mage::register

  2. Bezpośrednio pobierz obiekt bloku i ustaw właściwości danych w pobranym obiekcie bloku po uruchomieniu loadLayout

  3. Wywołaj metody na obiektach blokowych w phtmlplikach i pozwól obiektom blokowym używać warstwy modelu / bazy danych do odczytu danych zapisanych wcześniej w akcji kontrolera

Wydaje się, że używanie metod obiektów blokowych do odczytu z bazy danych nadal działa w Magento 2 - co jest odpowiednie dla niektórych rodzajów operacji. Jednak,

  1. W Magento 2 nie ma już globalnego rejestru (czy istnieje?)

  2. System układu działa teraz, tworząc obiekt strony za pomocą fabryki, i nie możesz pobierać odniesień do bloków w taki sam sposób, jak w Magento 1

Czy w Magento 2 można przesyłać dane bezpośrednio z akcji kontrolera do widoku? A może jest to zbyt bezpośredni wzór dla nowego wspaniałego świata Design Pattern ™ Magento? Jeśli jest to zbyt bezpośredni wzorzec, co należy zrobić, jeśli istnieją jakieś obliczone informacje, które chcemy wyświetlić w szablonie, ale nie chcemy przechowywać tych informacji w systemie stanowym (tzn. Nie chcemy zapisywać ich w Baza danych)

Mogę wymyślić kilka różnych sposobów na zhakowanie tego razem - ale interesuje mnie, jak Magento 2 chce, abyś to zrobił.

Uwaga : Zdaję sobie sprawę, że można pobrać instancję bloku w akcji kontrolera za pomocą czegoś takiego

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

var_dump(spl_object_hash($block));

Kod podstawowy Magento 2 robi to często. Jednak - obiekt bloku pobrany z obiektu kontrolera wydaje się być innym obiektem niż jest dostępny w phtmlszablonie za pośrednictwem jednego $thislub $block(pierwszy ( $this) wydaje się być obiektem, który faktycznie renderuje szablon, podczas gdy drugi ( $block) wydaje się być wystąpienie typu Magento Block).

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

Mówię „wydaje się być”, ponieważ jeśli ustawię dane w metodzie akcji kontrolera, nie będą one dostępne w phtmlszablonie - i jeśli porównam spl_object_hashpowyższe wyniki, otrzymam trzy różne wartości skrótu. Jestem jednak na tyle nowy, że powyższy może być innym błędem, który popełniłem - więc jeśli udało Ci się ustawić dane na blokach i pobrać je w szablonie, chciałbym o tym usłyszeć !

Alan Storm
źródło

Odpowiedzi:

17

Jeśli chodzi o nr 1, rejestr nadal istnieje, bardzo podobny do tego, co znasz z Magento 1. Po prostu został przeniesiony. Widzieć:\Magento\Framework\Registry

Dodaj go do konstruktora za pomocą wstrzykiwania zależności, a następnie będziesz mógł użyć swoich znanych $registry->register($key, $value)i $registry->registry($key)metod do przechowywania / uzyskiwania dostępu do danych.

Polecam przeszukiwać przestrzeń nazw \ Magento \ Framework, jeśli jeszcze tego nie zrobiłeś. Wiele z tego, co wcześniej było dostępne z Maga lub aplikacji, wciąż tam jest, po prostu się podziel.

Jeśli chodzi o najlepsze praktyki, nie mogę na to odpowiedzieć, ale spodziewam się, że odpowiedzią byłoby utrzymanie jak największej logiki poza kontrolerem. Patrzenie na rdzeń jest prawdopodobnie najlepszym wyborem. Na przykład zobacz stronę edycji adresu klienta: Kontroler podstawowy ; obszerny blok - w tym pobieranie adresu i ładowanie, jeśli to konieczne. Zajmują się tym bezpośrednio w bloku; nie robią tego w kontrolerze, a następnie przekazują.

Ryan Hoerr
źródło
2
Sztuczka polega oczywiście na tym, aby wiedzieć, na które części jądra patrzeć, a które ignorować :) Dzięki za wskazówki, +1 za przydatne informacje!
Alan Storm
1
+1 za ostatni akapit. Jeśli chcesz udostępnić część obliczonej wartości, umieść zachowanie obliczeniowe w oddzielnym obiekcie i wywołaj go z bloków, które wymagają tej wartości. Rejestr jest odradzany, ponieważ jest to globalny stan zmienny i nigdy nie masz pewności, co otrzymasz. Odradzane jest także bezpośrednie adresowanie bloków z akcji, ponieważ nigdy nie masz pewności, czy blok jest obecny na stronie (układ może go zabić)
Anton Kril
@AntonKril, a co z pomocnikami renderera stron? Pomocnik strony CMS, pomocnik widoku produktu, czy mają one oddzielić renderowanie od żądania HTTP?
Ivan Chepurnyi
5

Należy nie Przekazywanie zmiennych z akcji kontrolera do widoku. Użyj bloku, aby przekazać zmienne do widoku (silnik szablonów).

KAndy
źródło
Dlaczego? Jak możesz przekazać parametry get / post z bloku do widoku? Czy większość logiki nie przekazuje ich z kontrolera do wyświetlenia?
LucScu,
Użyj obiektu żądania w blokach. Jeśli zablokujesz pobieranie danych z kontrolera za pośrednictwem Rejestru, nie możesz używać bloków z innymi kontrolerami. Nazywa się to łączeniem
czasowym
Używam $ block-> assign (), aby przekazywać parametry żądania z kontrolera do bloku. Czy to również złe praktyki?
LucScu,
Odradzane jest także bezpośrednie adresowanie bloków z akcji, ponieważ nigdy nie masz pewności, czy blok jest obecny na stronie.
KAndy
W moim przypadku jestem pewien, ponieważ jest to niestandardowy scenariusz, w którym kontroler, układ i blok są kontrolowane tylko przez mój kod, więc myślę, że parametry logiki przekazują parametry żądania z kontrolera do bloku. Dziękujemy za odpowiedzi!
LucScu,