Intento encontrar la mejor manera de representar HTML a través de AJAX en Magento 2.
Forma 1: uso del controlador sin diseño
Archivo 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());
}
}
Forma 2: uso del controlador con diseño personalizado
Archivo 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();
}
}
Archivo 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>
Archivo 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>
En mi opinión, la mejor práctica parece ser el camino 2 porque separa la lógica del controlador.
Pero el problema con Way 2 es que se generan <body>y <head>con CSS/ JS, por lo que no es un HTML completamente limpio con solo mi plantilla de bloque.
- ¿Estoy usando el diseño personalizado de forma incorrecta?
- ¿El Camino 1 se considera una buena práctica?
- ¿Hay alguna otra forma de hacer eso?
fuente


Fuera de la caja, Magento no utiliza ninguno de esos métodos para representar HTML a través de AJAX.
Por lo que he visto, cada vez que hay que hacer algo así, JSON se utiliza para transportar el resultado.
Ejemplo de
Magento/Checkout/Controller/Cart/Add:Luego, Magento 2 usa un nuevo mecanismo llamado secciones, para manejar los datos en la interfaz y actualizar los bloques específicos que deben actualizarse, puede obtener más información sobre las secciones en estas preguntas y respuestas: /magento//a/ 143381/2380
EDITAR con respecto a la segunda parte de mi respuesta: como dijo Max en el comentario, las secciones solo se usan con datos específicos del cliente y usar esta funcionalidad en lugar de cada llamada AJAX no es la solución correcta.
fuente
En mi ejemplo, no puedo usar
sectionsporque no lo escustomer datay no es después de unaPUT/POSTacción, pero usando laRaphael at Digital Pianismrespuesta descubrí cómo Magento renderiza las secciones.Si tomamos el ejemplo de la
cartsección, use el método\Magento\Customer\CustomerData\SectionPool::getSectionDataByNamespara recuperar datos de las secciones. Esto nos lleva a\Magento\Checkout\CustomerData\Cart::getSectionDatauna única matriz que contiene áreas de la sección, incluyendo$this->layout->createBlock('Magento\Catalog\Block\ShortcutButtons')->toHtml()Dependiendo de eso, aquí está la clase de controlador final:
fuente