Staram się znaleźć najlepszy sposób renderowania HTML przez AJAX w Magento 2.
Sposób 1: Korzystanie z kontrolera bez układu
Plik Foo/Bar/Controller/Popin/Content.php
<?php
namespace Foo\Bar\Controller\Popin;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
/**
* Class Content
*/
class Content extends Action
{
/**
* Content constructor.
*
* @param Context $context
*/
public function __construct(
Context $context
) {
parent::__construct($context);
}
/**
*
*/
public function execute()
{
/** @var \Magento\Framework\View\Layout $layout */
$layout = $this->_view->getLayout();
/** @var \Foo\Bar\Block\Popin\Content $block */
$block = $layout->createBlock(\Foo\Bar\Block\Popin\Content::class);
$block->setTemplate('Foo_Bar::popin/content.phtml');
$this->getResponse()->setBody($block->toHtml());
}
}
Sposób 2: Używanie kontrolera z niestandardowym układem
Plik Foo/Bar/Controller/Popin/Content.php
<?php
namespace Foo\Bar\Controller\Popin;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
/**
* Class Content
*/
class Content extends Action
{
/**
* Content constructor.
*
* @param Context $context
*/
public function __construct(
Context $context
) {
parent::__construct($context);
}
/**
*
*/
public function execute()
{
$this->_view->loadLayout();
$this->_view->renderLayout();
}
}
Plik Foo/Bar/view/frontend/page_layout/ajax-empty.xml
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
<container name="root"/>
</layout>
Plik Foo/Bar/view/frontend/layout/foo_bar_popin_content.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="ajax-empty" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="root">
<block class="Foo\Bar\Block\Popin\Content" name="foo_bar_popin_content" template="Foo_Bar::popin/content.phtml" cacheable="false"/>
</referenceContainer>
</body>
</page>
IMO najlepszą praktyką wydaje się być Way 2, ponieważ oddziela logikę od kontrolera.
Ale problem z Drogą 2 jest to, że <body>
i <head>
z CSS
/ JS
są generowane więc to nie jest pełny HTML czyszczone tylko mojego szablonu bloku w nim.
- czy używam niestandardowego układu w niewłaściwy sposób?
- Czy Way 1 jest uważane za dobrą praktykę?
- Czy są na to inne sposoby?
źródło
Po wyjęciu z pudełka Magento nie używa żadnej z tych metod do renderowania HTML przez AJAX.
Z tego, co widziałem, za każdym razem, gdy trzeba coś takiego zrobić, JSON służy do przenoszenia wyniku.
Przykład z
Magento/Checkout/Controller/Cart/Add
:Następnie Magento 2 korzysta z nowego mechanizmu zwanego sekcjami, aby obsłużyć dane w interfejsie użytkownika i zaktualizować określone bloki, które wymagają aktualizacji. Więcej informacji na temat sekcji można znaleźć w tym pytaniu: /magento//a/ 143381/2380
EDYCJA dotycząca drugiej części mojej odpowiedzi: jak stwierdził Max w komentarzu, sekcje są używane tylko z danymi specyficznymi dla klienta i używanie tej funkcji zamiast każdego wywołania AJAX nie jest właściwym rozwiązaniem.
źródło
W moim przykładzie nie mogę używać,
sections
ponieważ tak nie jestcustomer data
i nie jest po akcjiPUT
/,POST
ale używającRaphael at Digital Pianism
odpowiedzi zorientowałem się, jak Magento renderuje sekcje.Jeśli weźmiemy przykład
cart
sekcji, użyj metody\Magento\Customer\CustomerData\SectionPool::getSectionDataByNames
do pobrania danych z sekcji. To prowadzi nas do\Magento\Checkout\CustomerData\Cart::getSectionData
jednej tablicy zawierającej obszary tej sekcji, w tym$this->layout->createBlock('Magento\Catalog\Block\ShortcutButtons')->toHtml()
W zależności od tego tutaj jest ostateczna klasa Controller:
źródło