Я пытаюсь найти лучший способ визуализации HTML через AJAX в Magento 2.
Способ 1: использование контроллера без макета
файл 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());
}
}
Способ 2: использование контроллера с пользовательским макетом
файл 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();
}
}
файл 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>
файл 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, лучшая практика, кажется, путь 2, потому что он отделяет логику от контроллера.
Но проблема с путём 2 заключается в том, что <body>
и <head>
с CSS
/ JS
генерируются, так что это не полностью очищенный HTML с только моим блочным шаблоном.
- я использую пользовательский макет неправильно?
- Является ли Путь 1 хорошей практикой?
- Есть ли другие способы сделать это?
источник
Изначально Magento не использует ни один из этих методов для рендеринга HTML через AJAX.
Из того, что я видел, каждый раз, когда нужно это делать, для передачи результата используется JSON.
Пример из
Magento/Checkout/Controller/Cart/Add
:Затем Magento 2 использует новый механизм, называемый разделами, для обработки данных на внешнем интерфейсе и обновления конкретных блоков, которые необходимо обновить, вы можете узнать больше о разделах в этом разделе вопросов и ответов: /magento//a/ 143381/2380
РЕДАКТИРОВАТЬ относительно второй части моего ответа: как указано Максом в комментарии, разделы используются только с данными конкретного клиента, и использование этой функции вместо каждого вызова AJAX не является правильным решением.
источник
В моем примере я не могу использовать,
sections
потому что это не так,customer data
и это не послеPUT
/POST
действия, но используяRaphael at Digital Pianism
ответ, я выяснил, как Magento визуализирует разделы.Если мы возьмем пример
cart
раздела, он использует метод\Magento\Customer\CustomerData\SectionPool::getSectionDataByNames
для извлечения данных из разделов. Это приводит нас к\Magento\Checkout\CustomerData\Cart::getSectionData
одному массиву, содержащему области раздела, в том числе$this->layout->createBlock('Magento\Catalog\Block\ShortcutButtons')->toHtml()
В зависимости от этого вот последний класс контроллера:
источник