Magento 2 - วิธีเพิ่มฟิลด์ที่กำหนดเองเพื่อชำระเงินและส่งไป


49

บทช่วยสอนทั้งหมดครอบคลุมเฉพาะการเพิ่มเขตข้อมูล แต่การบันทึกค่าของไฟล์นี้ถูกข้าม #mindblown ฉันไม่รู้ว่าทำไมมันเป็นส่วนที่สำคัญที่สุดในการเพิ่มฟิลด์หรือฟอร์มใด ๆ

ฉันพยายามติดตามMagento docsแต่ ... มันแย่มาก

สำหรับวัตถุประสงค์ในการทดสอบฉันพยายามเพิ่มเขตข้อมูลอื่นลงในที่อยู่สำหรับจัดส่งเพียงเพื่อละเว้นขอบเขตที่กำหนดเองชุดข้อมูลที่กำหนดเองผู้ให้บริการข้อมูลที่กำหนดเองและสิ่งอื่น ๆ ที่ไม่มีเอกสารซึ่งดูแปลกเกินไปสำหรับฉัน

ฉันไม่รู้ว่าแบบฟอร์มนั้นหมายถึง "คงที่" หรือ "ไดนามิก" สำหรับฉันแบบฟอร์มเช็คเอาต์ทั้งหมดจะถูกสร้างขึ้นแบบไดนามิกที่ด้านบนของเทมเพลต KnockoutJS แต่ ... เมื่อฉันลองใช้วิธี "คงที่" ฉันสามารถเพิ่มอินพุตที่นี่ (ดังนั้นจึงเป็นรูปแบบคงที่หรือไม่?)

ครั้งแรกฉันพยายามที่จะแก้ปัญหาว่าทำไมสิ่งที่น่าพิศวงสังเกตได้เพียงแค่ละเว้นสาขาของฉันในระหว่างการแยกและการส่งข้อมูล ฉันพบว่าฟิลด์ของฉันมีnameพารามิเตอร์ที่ว่างเปล่าแต่ฉันไม่สามารถจัดการวิธีการแก้ไขปัญหานี้ได้ IMO มันควรจะส่งผ่านไปยัง UI renderer องค์ประกอบผ่านinputNameพารามิเตอร์เดียวกับตัวเลือกอื่น ๆ เช่นdisabled, placeholderฯลฯ (พารามิเตอร์อื่น ๆ ทำงานได้ดีฉันจะตรวจสอบการตั้งค่าที่เกิดจาก XML ของฉันที่จะเริ่มต้นโมดูลเช็คเอาท์และดูดีสำหรับฉัน)

อันดับที่สองฉันพยายามใช้วิธี "ไดนามิก" ด้วยการสร้างปลั๊กอินด้วยLayoutProcessorและส่งผ่านข้อมูลเดียวกันทั้งหมด ... และตอนนี้ฉันมีฟิลด์ที่มีnames แต่การส่งยังไม่ทำงานเลย

หลังจากที่ขุดลงใน JS ฉันพบว่าการเตรียมคำขอนี้ถูกเก็บรักษาไว้ในmodule-checkout/view/frontend/web/js/model/shipping-save-processor/default.jsไฟล์ซึ่งขึ้นอยู่กับmodule-checkout/view/frontend/web/js/model/quote.jsว่ามีการกำหนด / สร้างสิ่งที่น่าสังเกตที่น่าพิศวง

อย่างใดmodule-checkout/view/frontend/web/js/model/address-converter.jsอัปเดตสิ่งที่สังเกตได้นี้และขึ้นอยู่กับmodule-checkout/view/frontend/web/js/model/new-customer-address.jsที่ฉันพบตัวเลือกการกำหนดค่าที่น่าสนใจในที่สุด - รายการของฟิลด์ที่อยู่ทั้งหมด

เมื่อฉันเพิ่มเขตข้อมูลของฉันที่นี่สคริปต์เริ่มการแยกวิเคราะห์และส่งพวกเขา OFC ฉันได้รับ 500 แบ็กเอนด์ b / c ไม่รู้จักพวกเขา ... (ไม่ถามฉันไม่ใช่ dev แบ็กเอนด์)

ดังนั้นคำถามของฉันมาที่นี่:

  • เป็นวิธีที่ถูกต้องในการจัดการกับการปรับแต่งประเภทนี้หรือไม่? (b / c ดูแปลกสำหรับฉัน)
  • จะส่งค่าของฟิลด์ที่ไม่เกี่ยวข้องกับที่อยู่ใหม่ได้อย่างไร ฉันไม่เห็นการกำหนดค่าที่คล้ายกันทุกที่ ในกรณีของฉันฉันต้องการส่งคำสั่งซื้อ (textarea) และคำขอใบแจ้งหนี้ (ช่องทำเครื่องหมาย) ทั้งสองไม่ควรถูกบันทึกเป็นที่อยู่ b / c ผู้ใช้บางคนอาจต้องการบันทึกที่อยู่นี้เพื่อใช้ในอนาคต
  • มีเอกสารเกี่ยวกับรูปแบบ "คงที่" และ "ไดนามิก" หรือตัวอย่าง / การเปรียบเทียบบ้างไหม? มันควรค่ากับการคิดแบบนี้ไหม

คำถามที่มีอยู่เพิ่มเติม:

  • ทำไมสิ่งนี้จึงไม่สอดคล้องกันอย่างนั้นเหรอ? ทำไมฉันต้องกำหนดพารามิเตอร์จำนวนมากในไฟล์ XML / PHP ในขณะที่วีโอไอพีทุกคนสามารถแสดงอินพุตได้เท่านั้นและฉันต้องจัดการทุกอย่างด้วยตัวเอง

3
Magento Devdocs เพิ่งเพิ่มเอกสารใหม่เกี่ยวกับการใช้คอมโพเนนต์ UI เรากำลังอยู่ในขั้นตอนของการเขียนคู่มือใหม่ทั้งหมด ... แต่ยังมีวิธีที่จะไป โปรดดูที่devdocs.magento.com/guides/v2.1/ui_comp_guide/bk-ui_comps.html น่าเสียดายที่เรายังไม่ได้ดำเนินการตามหัวข้อแหล่งข้อมูลซึ่งเป็นสิ่งที่ดูเหมือนว่าคุณต้องการเป็นส่วนใหญ่ มีหัวข้อเกี่ยวกับโฟลว์การกำหนดค่าโดยใช้คอมโพเนนต์ UI ซึ่งอาจช่วยได้ ฉันจะพยายามหาคำตอบเพิ่มเติม
tanberry

ทำไมต้องเป็นฝันร้ายที่เพิ่มเขตข้อมูลอย่างง่ายในการชำระเงิน ฉันไม่เข้าใจ และเกือบทุกอย่างเป็นเรื่องที่ยาก
slayerbleast

@slayerbleast World กำลังเปลี่ยนแปลงการเรนเดอร์ฝั่งเซิร์ฟเวอร์กำลังจะตาย ดังนั้นมันจึงแตกต่างไม่ยากโดยไม่มีเหตุผล
igloczek

คำตอบ:


55

ฉันจะพยายามตอบคำถามของคุณ

  1. ไม่ นี่ไม่ใช่วิธีที่ถูกต้องในการเพิ่มแอตทริบิวต์ที่กำหนดเองไปยังแบบฟอร์มที่อยู่จัดส่ง new-customer-address.jsคุณไม่จำเป็นต้องแก้ไข แท้จริงแล้วไฟล์ JS นี้แสดงรายการแอตทริบิวต์ที่อยู่ที่กำหนดไว้ล่วงหน้าทั้งหมดและจับคู่ส่วนต่อประสานด้านหลังที่เกี่ยวข้อง\Magento\Quote\Api\Data\AddressInterfaceแต่วีโอไอพีให้ความสามารถในการส่งแอตทริบิวต์ที่กำหนดเองใด ๆ ไปยังแบ็กเอนด์โดยไม่ต้องแก้ไขคอมโพเนนต์แบ็กเอนด์ / ส่วนหน้า

    คอมโพเนนต์ JS ที่กล่าวถึงมีcustomAttributesคุณสมบัติ แอตทริบิวต์ที่กำหนดเองของคุณจะได้รับการจัดการโดยอัตโนมัติหาก$dataScopePrefixเป็น " shippindAddress.custom_attributes"

  2. หากฉันเข้าใจคำถามของคุณถูกต้องคุณมีข้อมูลที่ไม่ได้เป็นส่วนหนึ่งของที่อยู่ลูกค้า แต่คุณต้องส่งไปที่แบ็กเอนด์ด้วย คำตอบสำหรับคำถามนี้คือ:

    มันขึ้นอยู่กับ ตัวอย่างเช่นคุณสามารถเลือกวิธีการต่อไปนี้: เพิ่มแบบฟอร์มที่กำหนดเองไปยังหน้าเช็คเอาต์ที่มีเขตข้อมูลพิเศษทั้งหมดของคุณ (like comment, invoice request etc)เพิ่มตรรกะ JS ที่จะจัดการรูปแบบนี้ขึ้นอยู่กับเหตุการณ์บางอย่างและให้บริการที่กำหนดเองที่จะได้รับข้อมูลจากส่วนหน้าและร้านค้า เพื่อใช้ในอนาคต

  3. เอกสารทั้งหมดอย่างเป็นทางการที่เกี่ยวข้องกับการเช็คเอาต์ตั้งอยู่ที่http://devdocs.magento.com/guides/v2.1/howdoi/checkout/checkout_overview.html คำว่าสแตติกหมายถึงรูปแบบที่เขตข้อมูลทั้งหมดเป็นที่รู้จัก / กำหนดไว้ล่วงหน้าแล้ว (ตัวอย่างเช่น: แบบฟอร์มจะมี 2 ฟิลด์ข้อความที่มีป้ายกำกับที่กำหนดไว้ล่วงหน้าเสมอ) และไม่สามารถเปลี่ยนแปลงได้ตามการตั้งค่าบางอย่างในแบ็กเอนด์

    layout XML configurationรูปแบบดังกล่าวสามารถประกาศใช้ ในทางตรงกันข้ามคำไดนามิกหมายถึงรูปแบบที่ชุดของฟิลด์สามารถเปลี่ยนได้ (ตัวอย่างเช่น: แบบฟอร์มเช็คเอาต์สามารถมีฟิลด์มากขึ้น / น้อยลงตามการตั้งค่าการกำหนดค่า)

    ในกรณีนี้วิธีเดียวที่จะประกาศฟอร์มดังกล่าวคือการใช้LayoutProcessorปลั๊กอิน

  4. :) วีโอไอพีพยายามที่จะครอบคลุมกรณีการใช้งานที่เป็นไปได้มากที่สุดซึ่งอาจสำคัญต่อผู้ค้าระหว่างการใช้ / ปรับแต่งวีโอไอพีให้ได้มากที่สุด บางครั้งสิ่งนี้นำไปสู่สถานการณ์เมื่อบางกรณีใช้งานง่ายกลายเป็นความซับซ้อนมากขึ้น

หวังว่านี่จะช่วยได้

================================================== =======================

ตกลง ... ให้เขียนโค้ด;)

  1. โค้ด PHP ที่แทรกฟิลด์เพิ่มเติมใน LayoutProcessor

========

/**
 * @author aakimov
 */
$customAttributeCode = 'custom_field';
$customField = [
    'component' => 'Magento_Ui/js/form/element/abstract',
    'config' => [
        // customScope is used to group elements within a single form (e.g. they can be validated separately)
        'customScope' => 'shippingAddress.custom_attributes',
        'customEntry' => null,
        'template' => 'ui/form/field',
        'elementTmpl' => 'ui/form/element/input',
        'tooltip' => [
            'description' => 'Yes, this works. I tested it. Sacrificed my lunch break but verified this approach.',
        ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
       'required-entry' => true
    ],
    'options' => [],
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
];

$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

return $jsLayout;

ดังที่ฉันได้กล่าวไปแล้วสิ่งนี้จะเพิ่มเขตข้อมูลของคุณไปยังcustomAttributesคุณสมบัติของวัตถุที่อยู่ JS คุณสมบัตินี้ได้รับการออกแบบเพื่อให้มีที่อยู่ EAV ที่กำหนดเองและเกี่ยวข้องกับ\Magento\Quote\Model\Quote\Address\CustomAttributeListInterface::getAttributesวิธีการ

รหัสด้านบนจะจัดการการเก็บรักษาข้อมูลในเครื่องโดยอัตโนมัติในส่วนหน้า คุณจะได้รับค่าเขตข้อมูลของคุณจากการจัดเก็บในท้องถิ่นใช้checkoutData.getShippingAddressFromData()(ที่checkoutDataเป็นMagento_Checkout/js/checkout-data)

  1. เพิ่มมิกซ์อินเพื่อเปลี่ยนพฤติกรรมของ 'Magento_Checkout / js / action / set-shipping-information' (ส่วนประกอบนี้มีหน้าที่รับผิดชอบในการส่งข้อมูลระหว่างขั้นตอนการจัดส่งและการชำระเงินในการเรียกเก็บเงิน)

========

2.1 สร้างyour_module_name/view/frontend/requirejs-config.js


/**
 * @author aakimov
 */
var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                '<your_module_name>/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

2.2 สร้าง your_module_name / view / frontend / web / js / action / set-shipping-data-mixin.js


/**
 * @author aakimov
 */
/*jshint browser:true jquery:true*/
/*global alert*/
define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

        return wrapper.wrap(setShippingInformationAction, function (originalAction) {
            var shippingAddress = quote.shippingAddress();
            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            // you can extract value of extension attribute from any place (in this example I use customAttributes approach)
            shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});
  1. สร้าง your_module_name / etc / extension_attributes.xml

========

<?xml version="1.0"?>
<!--
/**
 * @author aakimov
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="custom_field" type="string" />
    </extension_attributes>
</config>

สิ่งนี้จะเพิ่มแอททริบิวต์ส่วนขยายลงในโมเดลที่อยู่ทางด้านหลัง แอตทริบิวต์ส่วนขยายเป็นหนึ่งในจุดส่วนขยายที่ Magento ให้ไว้ ในการเข้าถึงข้อมูลของคุณในแบ็กเอนด์คุณสามารถใช้:

// Magento will generate interface that includes your custom attribute
$value = $address->getExtensionAttributes()->getCustomField();

หวังว่านี้จะช่วยและจะถูกเพิ่มลงในเอกสารอย่างเป็นทางการ


ขอบคุณสำหรับคำตอบอเล็กซ์! ฉันพยายามcustom_attributesแต่ก็ไม่ได้ผลสำหรับฉัน นี่คือลักษณะของ LayoutProcessor.php` - gist.github.com/Igloczek/eaf4d2d7a0a04bd950110296ec3f7727แต่shipping-info หรือแม้แต่ localStorage checkout-dataก็ไม่มีข้อมูลนี้เลย
igloczek

โปรดดูคำตอบที่อัปเดตของฉันด้านบน;)
aakimov

4
เอกสารอย่างเป็นทางการในหัวข้อนี้มีอยู่แล้ว! devdocs.magento.com/guides/v2.1/howdoi/checkout/…
อเล็กซ์

1
จำเป็นต้องมีขั้นตอนพิเศษเพิ่มเติมหรือไม่ในการเก็บค่ากับคำสั่งซื้อ?
Alex Hadley

ฉันคิดว่าถ้าคุณมีรูปแบบคงที่จะดีกว่าที่จะแทรกเขตข้อมูลลงใน LayoutProcessor ผ่าน XML เช่นในตัวอย่างนี้: devdocs.magento.com/guides/v2.1/howdoi/checkout/ …
cjohansson

-1

จากประสบการณ์ของฉัน m2 ใช้ xml เพื่อกำหนดส่วนประกอบเช่นเขตข้อมูล ฯลฯ มันช่วยแก้จุดบกพร่องโต้ตอบกับข้อมูลได้ง่ายขึ้น ในฟิลด์ของ front-enders คุณควรพยายามแทนที่เทมเพลตการชำระเงินและเพิ่มฟิลด์ที่กำหนดเองของคุณในนั้น ด้วย KO ช่วยให้คุณสามารถทำงานและผูกข้อมูลจากส่วนหน้าและส่วนหลัง


4
เป็นคำแนะนำที่ผิดแม่แบบเช็คเอาต์ b / c ไม่มีและไม่ควรมีฟิลด์ป้อนข้อมูลที่เพิ่มด้วยตนเอง เราต้องใช้ KO เพื่อแสดงเทมเพลตในภูมิภาคที่เลือก (ทุกอย่างถูกสร้างขึ้นโดยใช้ส่วนประกอบ UI)
igloczek

คุณสามารถแบ่งปันตัวอย่างของการเพิ่ม ui-components ที่กำหนดเองในส่วนหน้าได้หรือไม่?
mrtuvn

ดังที่ @igloczek กล่าวว่าเป็นคำแนะนำที่ผิดเพราะแม่แบบการเช็คเอาต์ไม่ควรมีฟิลด์ป้อนข้อมูลที่เพิ่มด้วยตนเอง
diazwatson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.