【问题标题】:Upsell product prices missing in Magento 2 when block loaded with AJAX使用 AJAX 加载块时 Magento 2 中缺少追加销售产品价格
【发布时间】:2016-01-06 08:55:21
【问题描述】:

我正在开发一个使用 AJAX 加载追加销售产品的 Magento 2 模块。每个客户的追加销售产品可能不同,因此使用 AJAX 加载块以允许缓存破坏。

为此,我有一个自定义模块,其中我的块扩展了\Magento\Catalog\Block\Product\ProductList\Upsell。在 catalog_product_view.xml 的模块布局中,我有以下内容 -

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.upsell" remove="true" />
        <referenceContainer name="content.aside">
            <block class="MyCompany\MyModule\Block\Product\ProductList\Upsell"
                   name="personalised.product.upsell"
                   template="MyCompany_MyModule::upsell.phtml" />
        </referenceContainer>
    </body>
</page>

在我的 upsell.phtml 中 -

<div id="personalised-upsells-container" data-role="personalised-upsells"></div>
<script type="text/x-magento-init">
    {
        "*": {
            "MyCompany_MyModule/js/upsell": {
                "upsellAjaxUrl": "<?php echo $block->getUpsellAjaxUrl(); ?>"
            }
        }
    }
</script>

getUpsellAjaxUrl() 生成 http://magento2.dev/personalised/products/upsellAjax/id/6

我的 upsell.js -

define([
    'jquery',
    'upsellProducts'
], function($) {

    function getUpsellContent(url) {
        $.ajax({
            url: url,
            dataType: 'html'
        }).done(function (data) {
            $('#personalised-upsells-container').html(data).promise().done(function(){
                $('.upsell').upsellProducts();
            });
        });
    }

    return function (config, element) {
        getUpsellContent(config.upsellAjaxUrl);
    };
});

我的控制器 (upsellAjax) -

class UpsellAjax extends ProductController
{
    public function execute()
    {
        $productId = (int) $this->getRequest()->getParam('id');
        $product = $this->loadProduct($productId);
        if (!$product) {
            return false;
        }
        /** @var \Magento\Framework\View\Result\Layout $resultLayout */
        $resultLayout = $this->resultFactory->create(ResultFactory::TYPE_LAYOUT);
        return $resultLayout;
    }
}

我的personalised_products_upsellajax.xml -

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <container name="root">
        <block class="MyCompany\MyModule\Block\Product\ProductList\Upsell" name="product.info.personalised.upsell" template="Magento_Catalog::product/list/items.phtml">
            <arguments>
                <argument name="type" xsi:type="string">upsell</argument>
            </arguments>
        </block>
    </container>
</layout>

正如您所料,这会通过 ajax 正确加载产品追加销售块,将 HTML 推送到我的容器中,然后初始化页面上的 upsellProducts 小部件。我的追加销售产品按预期显示,但没有价格。

我已经尝试了一些方法来调试这种情况,但据我所知,它无法在 getProductPriceHtml() 方法中的 \Magento\Catalog\Block\Product\AbstractProduct 的第 428 行加载 priceRender。当通过 AJAX 加载块时,$priceRender = $this-&gt;getLayout()-&gt;getBlock('product.price.render.default'); 行总是返回 false

这也是当我使用我的块替换布局中的默认块(personalised_products_upsellajax.xml)时的情况,例如

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <container name="root">
        <block class="Magento\Catalog\Block\Product\ProductList\Upsell" name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
            <arguments>
                <argument name="type" xsi:type="string">upsell</argument>
            </arguments>
        </block>
    </container>
</layout>

我认为这可能与首先在我的布局中删除追加销售块有关,即&lt;referenceBlock name="product.info.upsell" remove="true" /&gt; 我决定注释掉这行,导致出现两个追加销售块,一个是默认加载的块,另一个是另一个是我的 AJAX 块。默认块显示正确信息的结果相同,但我的 AJAX 块仍然缺少价格。

任何帮助将不胜感激。

【问题讨论】:

  • 你找到解决办法了吗?

标签: php ajax magento magento2


【解决方案1】:

我遇到了同样的问题:product.price.render.default 块需要在布局中可用,以及它的一些子块,才能呈现价格。答案的想法很简单:因为这个块是为 default 句柄加载的,所以通过在请求的早期添加它来确保这个句柄在布局中可用:

public function __construct(Context $context, LayoutInterface $layout)
{
    parent::__construct($context);

    $this->layout = $layout;
    $this->layout->getUpdate()->addHandle('default');
}

【讨论】:

  • 根据我的经验这是可行的,尽管使用empty 句柄可能会更好,所以$this-&gt;_layout-&gt;getUpdate()-&gt;addHandle('empty'); 默认句柄会产生大量不必要的块及其逻辑,而 Magento 添加了价格渲染器通过empty 句柄阻止,仅此而已。
【解决方案2】:

你可以试试:

<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <container name="root">
        <block class="Magento\Catalog\Block\Product\ProductList\Upsell" name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
            <arguments>
                <argument name="type" xsi:type="string">upsell</argument>
            </arguments>
        </block>
        <block class="Magento\Framework\Pricing\Render" name="product.price.render.default">
            <arguments>
                <argument name="price_render_handle" xsi:type="string">catalog_product_prices</argument>
                <argument name="use_link_for_as_low_as" xsi:type="boolean">true</argument>
            </arguments>
        </block>
    </container>
</layout>

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
【解决方案3】:

我最近遇到了同样的问题,经过大量挖掘和搜索,我们似乎找到了解决方案。将&lt;update handle="empty"/&gt; 添加到布局文件似乎可以解决问题并显示定价。所以在你的情况下,布局最终看起来像

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<update handle="empty"/>
        <container name="root">
            <block class="MyCompany\MyModule\Block\Product\ProductList\Upsell" name="product.info.personalised.upsell" template="Magento_Catalog::product/list/items.phtml">
                <arguments>
                    <argument name="type" xsi:type="string">upsell</argument>
                </arguments>
            </block>
        </container>
    </layout>

我无法解释它为什么起作用。我通过查看 1column 布局并以此为基础到达这里。到目前为止,我们已经在两个不同的地方使用它来解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多