Magento 2: ส่วนลูกค้า / section.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โมดูลในบางวิธี

  • ส่วนเหล่านั้นคืออะไร? คุณจะกำหนดส่วนได้อย่างไร
  • การอัพเดทส่วนจะถูกกระตุ้นอย่างไร
  • (ไม่บังคับ) ฉันจะแก้ไขรหัสทดสอบเพื่ออัปเดต minicart ได้อย่างไรเมื่อฉันไปถึงหน้ารถเข็น

สิ่งนี้ทริกเกอร์ในตัวควบคุมและการดำเนินการอ้างอิงเช่นโดยวิธีการดำเนินการหรือวิธีอื่น ๆ ?
LM_Fielding

1
@LM_Fielding เห็นฉันเพิ่งโพสต์คำตอบ: magento.stackexchange.com/a/142350/2380
Raphael ที่ Digital Pianism

คำตอบ:


82

ส่วนเหล่านั้นคืออะไร?

ส่วนคือส่วนของข้อมูลลูกค้าที่จัดกลุ่มเข้าด้วยกัน แต่ละส่วนจะถูกแทนด้วยคีย์ที่ใช้ในการเข้าถึงและจัดการข้อมูลและข้อมูลเอง วีโอไอพีโหลดส่วนโดยการร้องขอ AJAX เพื่อและแคชโหลดข้อมูลในการจัดเก็บในท้องถิ่นภายใต้เบราว์เซอร์ที่สำคัญ/customer/section/load/ mage-cache-storageวีโอไอพีติดตามเมื่อมีการเปลี่ยนแปลงบางส่วนและโหลดส่วนที่อัพเดทโดยอัตโนมัติ

คุณจะกำหนดส่วนได้อย่างไร

ส่วนที่กำหนดไว้ใน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>

ดังนั้นที่นี่สองส่วนใหม่มีการลงทะเบียนและcart และการดำเนินการและให้ข้อมูลที่แท้จริงเป็นผลมาจากวิธีการdirectory-dataMagento\Checkout\CustomerData\CartMagento\Checkout\CustomerData\DirectoryDataMagento\Customer\CustomerData\SectionSourceInterfacegetSectionData

การอัพเดทส่วนจะถูกกระตุ้นอย่างไร

วีโอไอพีอนุมานว่าข้อมูลส่วนตัวของลูกค้าที่มีการเปลี่ยนแปลงเมื่อลูกค้าส่งคำขอการปรับเปลี่ยนบางส่วนของรัฐ ( POST, PUT, DELETE) เพื่อลดภาระในเซิร์ฟเวอร์พัฒนาควรระบุว่าการดำเนินการ (หรือคำขอ) etc/section.xmlการปรับปรุงที่ส่วนข้อมูลของลูกค้าใน

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

ชื่อการดำเนินการเป็นรูปแบบคีย์การกระทำ เมื่อผู้ใช้เรียกร้องให้ดำเนินการที่ตรงกับรูปแบบที่ระบุวีโอไอพีจะตรวจพบว่าส่วนที่เกี่ยวข้องนั้นล้าสมัยแล้วและโหลดซ้ำอีกครั้ง หากชื่อการกระทำ*หมายถึงส่วนนั้นจะได้รับการอัปเดตในคำขอ 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ซึ่งหมายความว่าว่าเมื่อรูปแบบใด ๆ ที่โพสต์ (ที่มีการโพสต์หรือวิธีการ PUT) ไปยังเซิร์ฟเวอร์หรือเมื่อ JavaScript ส่ง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

นอกจากนี้มีเพียงสองบันทึก:

  • ทั้งหมดที่อธิบายไว้ที่นี่เป็นการใช้งานภายในและอาจมีการเปลี่ยนแปลงดังนั้นคุณสามารถใช้ส่วนได้อย่างปลอดภัยและคาดหวังว่าจะอัปเดตส่วนเมื่อมีการเรียกใช้การกระทำ POST หรือ PUT หรือ DELETE ที่ระบุ
  • หากคุณแน่ใจว่าคุณต้องการอัปเดตบางส่วนคุณสามารถทำสิ่งนี้ได้ตลอดเวลา: require('Magento_Customer/js/customer-data').reload(['cart'], false)

ขอบคุณมากสำหรับสิ่งนั้น วิธีใดที่คุณสามารถบอกได้ว่าทำไมรหัสในคำถามของฉันไม่รีเฟรชมินิรถเข็นเมื่อฉันไปถึงหน้ารถเข็น
Raphael ที่ Digital Pianism

1
@RaphaelatDigitalPianism ฉันได้อัปเดตความคิดเห็นของฉันด้วยคำตอบ
Volodymyr Kublytskyi

ฉันกำลังโทรหาอาแจ็กซ์ที่กำหนดเองในหน้ารถเข็นฉันไม่ต้องการการโทรในส่วนโหลดลูกค้า ฉันจะหลีกเลี่ยงสิ่งนี้ได้อย่างไร magento.stackexchange.com/questions/156425/ …
seeni

5

การกระทำที่คุณกำหนดในแท็กควรปรากฏผ่านคำขอ POST เช่น:

นอกจากนี้หากคุณต้องการรีเฟรชข้อมูลลูกค้าในทุกส่วนเพียงใช้ (ดูผู้ขาย / วีโอไอพี / โมดูลลูกค้า / ฯลฯ / ส่วนหน้า / ส่วน. xml)

คุณสามารถดูที่ท้ายไฟล์vendor/magento/module-customer/view/frontend/web/js/section-‌​config.js
ค้นหารหัส:

$ (เอกสาร) .on ('ส่ง', ฟังก์ชั่น (เหตุการณ์) { 
    ส่วน var; 
    if (event.target.method.match (/ post | put / i)) { 
        section = sectionConfig.getAffectedSections (event.target.action);
        ถ้า (ส่วน) { 
            customerData.invalidate (ส่วน); 
        } 
    } 
});

นอกจากนี้คุณยังสามารถดูจุดสิ้นสุดของผู้ขายไฟล์ / magento / module-customer / view / frontend / web / js / section-config.js ค้นหารหัส $ (เอกสาร) .on ('ส่ง', ฟังก์ชั่น (เหตุการณ์) {var ส่วน; ถ้า (event.target.method.match (/ โพสต์ | ใส่ / i)) {section = sectionConfig.getAffectedSections (event.target.action) ถ้า (ส่วน) {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, ส่วนของฉัน. xml ไม่ได้พยายามอัปเดตรถเข็นเมื่อฉันส่งคำขอโพสต์ไปยัง url ในไฟล์ ... มีความคิดเห็นอะไรบ้าง?
LM_Fielding

@LM_Fielding ใช่ฉันมีคนคนเดียวกันอ่านคำตอบของฉัน
Raphael ที่ Digital Pianism

เพื่อให้มันใช้งานได้เราต้องเขียนสิ่งนี้? พฤติกรรมเริ่มต้นเสียหรือฉันเข้าใจผิด?
LM_Fielding

@LM_Fielding ดีฉันไม่รู้ว่านั่นเป็นเหตุผลที่ฉันถามคำถามนี้และฉันไม่ได้รับคำตอบที่ดีเกี่ยวกับมัน อย่างที่ฉันบอกว่านี่เป็นวิธี "แฮ็ค" ที่ฉันพบว่าทำได้
Raphael ที่ Digital Pianism

แน่นอนว่าใช้ URL แบบสัมพัทธ์สำหรับฉัน - มันไม่เรียกการอัปเดตส่วน
LM_Fielding

0

ฉันประสบปัญหาเดียวกับผู้เขียนคำถาม หลังจากไม่กี่ชั่วโมงของการวิจัยและการลดลงในเอกสารและรหัสหลักฉันก็มีทางออก ในกรณีของฉันฉันได้รับ ... / etc / frontend / section.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.