마 젠토 2 : 고객 섹션 /sections.xml은 어떻게 작동합니까?


49

최근 Magento 2에서 흥미로운 새로운 개념을 발견했습니다. 고객 섹션

여러분 중 일부는 sections.xml다음과 같은 파일이 있음을 알게 될 것입니다 .

<?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>

내가 이해 한 바에 따르면, 해당 파일은 해당 조치가 호출 될 때 업데이트 될 고객 섹션을 지정합니다.

예를 들어 Magento/Checkout/etc/frontend/sections.xml다음과 같은 부분이 나타났습니다 .

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

장바구니에 제품을 추가 한 후 미니 카트 업데이트가 시작됩니다.

etc/frontend/sections.xml해당 기능을 테스트하기 위해 다음 파일로 사용자 정의 모듈을 작성하려고했습니다 .

<?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>

그러나 장바구니 페이지에 도달했을 때 장바구니 섹션을 업데이트하려고 시도하지 않는 것 같습니다 (콘솔에 GET 요청 없음). 이 전체 섹션 기능은 Magento_Customer어떤 방식으로 모듈에 의해 처리되는 것처럼 보입니다 .

  • 정확히 그 섹션은 무엇입니까? 섹션을 어떻게 정의합니까?
  • 섹션 업데이트는 어떻게 트리거됩니까?
  • (선택 사항) 장바구니 페이지에 도달했을 때 미니 카트를 업데이트하기 위해 테스트 코드를 수정하려면 어떻게해야합니까?

이것은 컨트롤러에서 트리거되고 실행 메소드 또는 다른 방법으로 참조되는 조치입니까?
LM_Fielding

1
@LM_Fielding 내가 방금 답변을 게시했습니다 참조 : magento.stackexchange.com/a/142350/2380
Raphael at Digital Pianism

답변:


82

정확히 그 섹션은 무엇입니까?

섹션은 함께 그룹화 된 고객 데이터입니다. 각 섹션은 데이터 및 데이터 자체에 액세스하고 관리하는 데 사용되는 키로 표시됩니다. Magento는 AJAX 요청에 의해 섹션을 /customer/section/load/로드하고 키 아래의 브라우저 로컬 스토리지에로드 된 데이터를 캐시합니다 mage-cache-storage. Magento는 일부 섹션이 변경 될 때 추적하고 업데이트 된 섹션을 자동으로로드합니다.

섹션을 어떻게 정의합니까?

di.xml섹션 풀에 새 섹션을 추가하여 파일에 정의 된 섹션

<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>

그래서 여기에 두 개의 새로운 섹션은 등록 cartdirectory-data. Magento\Checkout\CustomerData\CartMagento\Checkout\CustomerData\DirectoryData구현 Magento\Customer\CustomerData\SectionSourceInterface및 결과로서 실제 데이터 제공 getSectionData방법.

섹션 업데이트는 어떻게 트리거됩니까?

마 젠토는 고객이 어떤 상태 수정 요청 (보낼 때 고객의 개인 데이터가 변경되는 것으로 가정 POST, PUT, DELETE)를. 서버의로드를 최소화하려면 개발자는의 고객 데이터 섹션에서 업데이트 할 작업을 지정해야합니다 etc/section.xml.

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

동작 이름은 동작 키 패턴입니다. 사용자가 지정된 패턴과 일치하는 조치를 호출하면 Magento는 해당 섹션이 오래되었음을 감지하고 다시로드합니다. 조치 이름이 *해당 되면 해당 POST 및 PUT 요청마다 섹션이 업데이트됩니다. 섹션 태그가 누락되면 모든 섹션이 업데이트됩니다.

따라서 개념적으로 이것은 장바구니 페이지가 풍부 할 때 미니 장바구니를 업데이트하는 데 잘못되었습니다. 이 시점에서 미니 카트 (또는 카트 섹션)가 이미 업데이트되어 있어야합니다.

고객 데이터에 대한 자세한 내용은 여기를 참조하십시오.


내부 구현

섹션이 업데이트되는시기와 방법을 이해하기 위해 구현을 살펴 보겠습니다. 이해의 열쇠는 파일 magento2ce/app/code/Magento/Customer/view/frontend/web/js/section-config.jsmagento2ce/app/code/Magento/Customer/view/frontend/web/js/customer-data.js입니다.

마지막에 두 이벤트 핸들러 중 하나가 ajaxComplete및에 등록됩니다 submit. 즉, 즉, 어떤 형태의 서버, 또는 자바 스크립트가 전송할 때 (POST 또는 PUT 방법으로) 배치 될 때 AJAX, POST또는 PUT요구를 상기 핸들러가 호출된다. 두 처리기 모두 비슷한 논리를 가지고 있습니다. Magento_Customer/js/section-config점검의 도움으로 섹션을 업데이트해야합니다. 일부 섹션을 업데이트해야하는 경우이 섹션 customerData.invalidate(sections)이 호출됩니다. 나중에 무효화 된 모든 섹션이 서버에서로드됩니다.

그렇다면 Magento_Customer/js/section-config어떤 섹션을 제거하고 어떤 작업을 수행해야하는지 어떻게 알 수 있습니까? 답은 다음과 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>

이러한 방식으로 서버는 병합 된 섹션 구성을 브라우저로 전달합니다.

따라서 모든 것을 가정하면 섹션은 POST 또는 PUT 양식 제출 또는 AJAX 요청에 의해서만 업데이트 될 수 있습니다

또한 두 가지 메모 만 있습니다.

  • 여기에 설명 된 모든 내용은 내부 구현이며 변경 될 수 있으므로 section.xml 만 안전하게 사용할 수 있으며 지정된 POST 또는 PUT 또는 DELETE 작업이 트리거 될 때 섹션 업데이트를 기대할 수 있습니다.
  • 확실하다면 일부 섹션을 업데이트해야하므로 항상 다음과 같이 할 수 있습니다. require('Magento_Customer/js/customer-data').reload(['cart'], false)

정말 감사합니다. 장바구니 페이지에 도달했을 때 내 질문의 코드가 미니 장바구니를 새로 고치지 않는 이유를 알 수있는 방법은 무엇입니까?
디지털 Pianism에서 라파엘

1
@RaphaelatDigitalPianism, 답변으로 내 의견을 업데이트했습니다
Volodymyr Kublytskyi

장바구니 페이지에서 사용자 정의 아약스 호출을하고 있는데이 고객로드 섹션 호출이 필요하지 않습니다. 어떻게 피할 수 있습니까? magento.stackexchange.com/questions/156425/…
seeni

5

태그에 정의한 작업은 POST 요청을 통해 실행되어야합니다. 예 :

또한 모든 섹션에서 고객 데이터를 새로 고치려면 다음을 사용하십시오 (공급 업체 /magento/module-customer/etc/frontend/sections.xml 참조).

파일의 끝을 볼 수도 있습니다 vendor/magento/module-customer/view/frontend/web/js/section-‌​config.js
. 코드를 찾으십시오.

$ (document) .on ( 'submit', 함수 (이벤트) { 
    var 섹션; 
    if (event.target.method.match (/ post | put / i)) { 
        섹션 = sectionConfig.getAffectedSections (event.target.action);
        if (섹션) { 
            customerData.invalidate (섹션); 
        } 
    } 
});

또한 파일 벤더 /magento/module-customer/view/frontend/web/js/section-config.js의 끝을 볼 수 있습니다. 코드 찾기 $ (document) .on ( 'submit', function (event) {var 섹션; if (event.target.method.match (/ post | put / i)) {섹션 = sectionConfig.getAffectedSections (event.target.action); if (섹션) {customerData.invalidate (섹션);}}}) ;
lemk0

3

내가 알아 낸 해키 방법 :

장바구니로 리디렉션되는 액션 클래스에서 다음을 수행합니다.

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

그런 다음 장바구니 페이지에 다음을 추가했습니다.

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

그런 다음 내 블록에는 다음이 있습니다.

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');
}

그리고 내 Refresh.php액션 클래스는 다음과 같습니다.

<?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, files.url에 게시물 요청을 보낼 때 section.xml이 장바구니를 업데이트하지조차 않습니다 ... 어떤 아이디어?
LM_Fielding

@LM_Fielding 그래, 난, 같은 사람이 있었다 내 대답 읽기
디지털 Pianism에서 라파엘을

작동하게하려면 이것을 써야합니까? 기본 동작이 깨지거나 오해입니까?
LM_Fielding

@ LM_Fielding 잘 나는 그것이 왜이 질문을했는지 잘 모르겠으며 그것에 대해 좋은 대답을 얻지 못했습니다. 내가 말했듯이 이것은 내가 그것을 발견 한 "해킹"방법입니다.
디지털 Pianism에서 라파엘

그것은 분명히 나를 위해 상대 URL을 사용하고 있었고 섹션 업데이트를 트리거하지 않습니다.
LM_Fielding

0

나는 질문의 저자와 같은 문제에 직면했다. 몇 시간 동안 문서와 핵심 코드를 연구하고 혼란스럽게 한 후에 갑자기 해결책을 얻었습니다. 제 경우에는 ... / etc / frontend / sections.xml 파일이 있습니다.

<?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>

그리고 그것은 일하고 싶지 않았습니다. 이 주제 와이 문제를 읽은 후 https://github.com/magento/magento2/issues/3287 나는 너무 혼란스러워 실험을 시작했습니다. 슬래시를 추가하는 데 도움이됩니다.

 <?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>

누군가가 솔루션을 찾는 데 더 적은 시간을 소비하는 데 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.