Ich versuche, den besten Weg zu finden, um HTML über AJAX in Magento 2 zu rendern.
Weg 1: Verwenden des Controllers ohne Layout
Datei 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());
}
}
Weg 2: Verwenden des Controllers mit benutzerdefiniertem Layout
Datei 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();
}
}
Datei 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>
Datei 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 scheint die beste Vorgehensweise der Weg 2 zu sein, da er die Logik vom Controller trennt.
Das Problem mit Way 2 ist jedoch, dass das <body>
und <head>
mit CSS
/ JS
generiert werden, sodass es sich nicht um ein vollständig bereinigtes HTML handelt, in dem nur meine Blockvorlage enthalten ist.
- verwende ich das benutzerdefinierte Layout falsch?
- Wird der Weg 1 als gute Praxis angesehen?
- Gibt es andere Möglichkeiten, das zu tun?
quelle
Standardmäßig verwendet Magento keine dieser Methoden, um HTML über AJAX zu rendern.
Soweit ich gesehen habe, wird JSON jedes Mal, wenn so etwas getan werden muss, verwendet, um das Ergebnis zu transportieren.
Beispiel aus dem
Magento/Checkout/Controller/Cart/Add
:Dann verwendet Magento 2 einen neuen Mechanismus namens Abschnitte, um die Daten im Frontend zu verarbeiten und die spezifischen Blöcke zu aktualisieren, die aktualisiert werden müssen. Weitere Informationen zu Abschnitten finden Sie in diesen Fragen und Antworten: /magento//a/ 143381/2380
BEARBEITEN Sie den zweiten Teil meiner Antwort: Wie von Max im Kommentar angegeben, werden Abschnitte nur mit kundenspezifischen Daten verwendet, und die Verwendung dieser Funktionalität anstelle jedes AJAX-Aufrufs ist nicht die richtige Lösung.
quelle
In meinem Beispiel kann ich nicht verwenden,
sections
weil es nicht istcustomer data
und es nicht nach einerPUT
/POST
Aktion ist, aber mitRaphael at Digital Pianism
Antwort habe ich herausgefunden, wie Magento Abschnitte rendert.Wenn wir das Beispiel eines
cart
Abschnitts nehmen, verwenden wir die Methode\Magento\Customer\CustomerData\SectionPool::getSectionDataByNames
, um Daten aus Abschnitten abzurufen. Dies führte uns zu\Magento\Checkout\CustomerData\Cart::getSectionData
einem einzelnen Array, das Bereiche des Abschnitts enthält, einschließlich$this->layout->createBlock('Magento\Catalog\Block\ShortcutButtons')->toHtml()
Abhängig davon ist hier die endgültige Controller-Klasse:
quelle