Magento 2: Müşteri bölümleri / bölümleri.xml nasıl çalışır?


49

Yakın zamanda Magento 2'de ilginç bulduğum yeni bir konsepte rastladım: müşteri bölümleri

Bazılarınız sections.xmlşuna benzeyen dosyaların varlığını fark etmiş olabilirsiniz :

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="sales/guest/reorder">
        <section name="cart"/>
    </action>
    <action name="sales/order/reorder">
        <section name="cart"/>
    </action>
</config>

Anladığım kadarıyla, bu dosyalar ilgili işlem çağrıldığında hangi müşteri bölümlerinin güncellenmesi gerektiğini belirtir.

Mesela Magento/Checkout/etc/frontend/sections.xmlaşağıdaki kısımdan haberdar oldum :

<action name="checkout/cart/add">
    <section name="cart"/>
</action>

Alışveriş sepetine bir ürün ekledikten sonra minicart güncellemesini tetikleyen şeydir.

etc/frontend/sections.xmlBu özelliği test etmek için aşağıdaki dosyaya sahip özel bir modül oluşturmaya çalıştım :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="checkout/cart/index">
        <section name="cart"/>
    </action>
</config>

Ancak alışveriş sepeti sayfasına ulaştığımda alışveriş sepetimi güncellemeye çalışmış gibi görünmüyor (konsolda GET isteği yok). Bu bütün bölüm işlevselliği Magento_Customermodül tarafından bir şekilde ele alınmış gibi görünüyor .

  • Bu bölümler tam olarak nedir? Bir bölümü nasıl tanımlarsınız?
  • Bölüm güncellemeleri nasıl tetiklenir?
  • (İsteğe bağlı) Sepet sayfasına ulaştığımda, mini sepeti güncellemek için test kodumu nasıl düzeltebilirim?

Bu, denetleyicide tetiklenir mi ve bir execute metodu veya başka bir yolla atıfta bulunulan eylem gibi mi?
LM_Fielding

1
@LM_Fielding az önce bir cevap gönderdim: magento.stackexchange.com/a/142350/2380
Raphael, Digital

Yanıtlar:


82

Bu bölümler tam olarak nedir?

Bir bölüm birlikte gruplandırılmış bir müşteri verisi parçasıdır. Her bölüm, verilere ve verilere erişmek ve bunları yönetmek için kullanılan anahtarla temsil edilir. Magento, AJAX isteğine göre bölümleri yükler /customer/section/load/ve yüklenen verileri anahtarın altındaki tarayıcı yerel deposuna önbelleğe alır mage-cache-storage. Magento bazı bölümler değiştirildiğinde izlenir ve güncellenmiş bölümü otomatik olarak yükler.

Bir bölümü nasıl tanımlarsınız?

di.xmlBölümler havuzuna yeni bir bölüm ekleyerek dosyada tanımlanan bölüm

<type name="Magento\Customer\CustomerData\SectionPoolInterface">
    <arguments>
        <argument name="sectionSourceMap" xsi:type="array">
            <item name="cart" xsi:type="string">Magento\Checkout\CustomerData\Cart</item>
            <item name="directory-data" xsi:type="string">Magento\Checkout\CustomerData\DirectoryData</item>
        </argument>
    </arguments>
</type>

Yani burada iki yeni bölüm kayıtlıdır cartve directory-data. Magento\Checkout\CustomerData\Cartve yöntemin sonucu olarak gerçek verileri Magento\Checkout\CustomerData\DirectoryDatauygular Magento\Customer\CustomerData\SectionSourceInterfaceve sağlar getSectionData.

Bölüm güncellemeleri nasıl tetiklenir?

Magento bir müşterinin bazı devlet modifikasyon istek gönderdiğinde müşterinin özel veri değiştiğinde varsayar ( POST, PUT, DELETE). Sunucu yükünü en aza indirmek için, geliştiricilerin hangi müşteri verileri bölümünde hangi eylemi (veya isteği) güncelleyeceğini belirtmesi gerekir etc/section.xml.

<action name="checkout/cart/add">
    <section name="cart"/>
</action>

İşlem adı, bir işlem anahtarı kalıbıdır. Bir kullanıcı belirtilen kalıba uyan bir eylemi aradığında, Magento ilgili bölümün eski olduğunu tespit eder ve tekrar yükler. Eylem adı bu ise *, bu bölüm her POST ve PUT isteğinde güncellenecektir. Bölüm etiketi kaçırılırsa tüm bölüm güncellenir.

Bu yüzden kavramsal olarak bu, sepeti sayfasını zenginleştirdiğinizde mini sepeti güncellemek yanlıştır. Bu noktada, mini alışveriş sepeti (veya alışveriş sepeti bölümü) zaten güncellenmelidir.

Müşteri Verileri hakkında daha fazla bilgiyi burada bulabilirsiniz.


Dahili Uygulama

Bölümlerin ne zaman ve nasıl güncellendiğini anlamak için uygulamaya geçelim. Anlamanın anahtarı, dosyalar magento2ce/app/code/Magento/Customer/view/frontend/web/js/section-config.jsve magento2ce/app/code/Magento/Customer/view/frontend/web/js/customer-data.js.

Son olayın sonunda, iki olay işleyicisinden biri için ajaxCompleteve kayıtlıdır submit. Bu demektir ki, herhangi bir şekilde bir sunucuya veya JavaScript bir gönderdiğinde (POST veya PUT yöntemlerle) gönderilen zaman AJAX, POSTya da PUTtalebi, yükleyiciler çağrılır. Her iki işleyicide de benzer bir mantık var: Magento_Customer/js/section-configkontrol yardımı ile güncellenen ya da olmayan herhangi bir bölüm olmalıdır. Bazı bölüm güncellenmesi gerekiyorsa o customerData.invalidate(sections)zaman denir. Ve daha sonra bütün geçersiz bölümler bir sunucudan yüklenir.

Peki Magento_Customer/js/section-confighangi bölümün kaldırılması ve hangi eylemde bulunulması gerektiğini nasıl bilebilir? Cevap içinde Magento/Customer/view/frontend/templates/js/section-config.phtml:

<script type="text/x-magento-init">
<?php
     /* @noEscape */ echo $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([
    '*' => ['Magento_Customer/js/section-config' => [
        'sections' => $block->getSections(),
        'clientSideSections' => $block->getClientSideSections(),
        'baseUrls' => array_unique([
            $block->getUrl(null, ['_secure' => true]),
            $block->getUrl(null, ['_secure' => false]),
        ]),
    ]],
]);
?>
</script>

Bu şekilde, bir sunucu birleştirilmiş bölümlerin yapılandırmasını bir tarayıcıya iletir.

Bunların hepsini varsayarsak, bölüm yalnızca POST veya PUT formu göndererek veya AJAX isteği ile güncellenebilir

Ayrıca, sadece iki not vardır:

  • burada açıklanan tüm iç uygulamalardır ve değiştirilebilir, bu nedenle yalnızca POST veya PUT veya DELETE eylemleri tetiklendiğinde güvenle yalnızca bölüm.xml kullanabilir ve bölüm güncellemelerini bekleyebilirsiniz.
  • Eğer bazı bölümleri gerçekten güncellemeniz gerektiğinden eminseniz, daima şöyle bir şey yapabilirsiniz: require('Magento_Customer/js/customer-data').reload(['cart'], false)

Bunun için harika teşekkürler. Sorumdaki kodun neden alışveriş sepetine ulaştığımda mini alışveriş sepetini yenilemediğini söylemenin bir yolu yok mu?
Raphael, Digital Pianism'de

1
@RaphaelatDigitalPianism, yorumumu yanıtla güncelledim
Volodymyr Kublytskyi

Sepet sayfasında özel bir ajax araması yapıyorum, bu müşteri yükleme bölümü çağrısına ihtiyacım yok. Bundan nasıl kaçınabilirim? magento.stackexchange.com/questions/156425/…
seeni

5

Etikette tanımladığınız eylem, POST isteği yoluyla başlatılmalıdır. Örneğin:

Ayrıca, tüm bilgileri müşteri verilerinin yenilemesini istiyorsanız, sadece kullanın (Satıcıya bakın / magento / module-customer / etc / frontend / section.xml)

Ayrıca dosyanın sonuna bakabilirsiniz vendor/magento/module-customer/view/frontend/web/js/section-‌​config.js
Kodu bulun:

$ (document) .on ('Gönder', işlev (olay) { 
    var bölümler; 
    if (event.target.method.match (/ post | put / i)) { 
        bölümleri = sectionConfig.getAffectedSections (event.target.action);
        eğer (bölümler) { 
            customerData.invalidate (bölümleri); 
        } 
    } 
});

Ayrıca, satıcı / magento / module-customer / view / frontend / web / js / section-config.js dosyasının sonuna da bakabilirsiniz. $ (Document) .on kodunu bulun. bölümleri; if (event.target.method.match (/ post | put / i)) {bölme = sectionConfig.getAffectedSections (event.target.action); ;
lemk0

3

Bunu yapmak için bulduğum bir hack yolu:

Sepetim yönlendiren eylem sınıfımda yapıyorum:

$this->_checkoutSession->setMinicartNeedsRefresh(true);

Sonra aşağıdakileri sepet sayfama ekledim:

<?php if ($this->isRefreshRequired()): ?>
    <script type="text/javascript">
        require( [ 'jquery' ], function ($)
        {
            $.ajax({
                url: '<?php echo $this->getRefreshUrl(); ?>',
                type: 'POST'
            });
        });
    </script>
<?php endif; ?>

Sonra bloğumda var:

public function isRefreshRequired()
{
    if ($this->_checkoutSession->getMinicartNeedsRefresh()) {
        $this->_checkoutSession->setMinicartNeedsRefresh(false);
        return true;
    } else {
        return false;
    }
}

/**
 * Get the refresh URL
 * @return string
 */
public function getRefreshUrl()
{
    return $this->getUrl('module/cart/refresh');
}

Ve Refresh.phpaksiyon dersim şöyle gözüküyor:

<?php

namespace Vendor\Module\Controller\Cart;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;

class Refresh extends Action
{

    /**
     * Dummy action class called via AJAX to trigger the section update
     */
    public function execute()
    {
        return $this->getResponse()->representJson(
            $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode(['success'=>true])
        );
    }
}

Raphael, dosyamın URL'sine bir gönderi isteği gönderdiğimde sepetim güncellemek bile istemiyor. Sepetinizde herhangi bir fikir var mı?
LM_Fielding

@LM_Fielding evet Aynı insanlara sahiptim, cevabımı oku
Raphael, Digital Pianism'de

Yani işe yaraması için bunu yazmalı mıyız? Varsayılan davranış bozuk mu yoksa yanlış mı anladım?
LM_Fielding

@LM_Fielding iyi bilmiyorum bu yüzden bu soruyu sordum ve bu konuda iyi bir cevap alamadım. Dediğim gibi, bunu yaparken bulduğum "hacky" yoludur.
Raphael, Digital Pianism'de

Kesinlikle benim için göreli bir URL kullanıyordu - bölüm güncellemesini tetiklemiyor.
LM_Fielding

0

Sorunun yazarı ile aynı problemle karşılaştım. Belgelendirme ve temel kod konusunda birkaç saat araştırma ve inceleme yaptıktan sonra aniden bir çözüm buldum. Benim durumumda ... / etc / frontend / section.xml dosyası var

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="roadsignconf/index/addtocart">
        <section name="cart"/>
    </action>
</config>

Ve çalışmak istemiyordu. Bu konuyu ve bu konuyu okuduktan sonra https://github.com/magento/magento2/issues/3287 denemek için kafam çok karıştı. Benim için eğik çizgi eklemeye yardımcı olur:

 <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
        <action name="/roadsignconf/index/addtocart/">
            <section name="cart"/>
        </action>
    </config>

Umarım birisinin çözüm bulmak için daha az zaman harcamasına yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.