Magento 2 - Як додати користувальницьке поле для оформлення замовлення, а потім надіслати його


49

Усі навчальні посібники охоплюють лише додавання полів, але значення збереження цих файлів пропускається #mindblown. Я не знаю чому, це найважливіша частина додавання будь-якого поля чи форми.

Я намагався слідкувати за документами Magento , але ... це відстійно.

З метою тестування я намагаюся додати інші поля до адреси доставки, просто ігнорувати власні області застосування, спеціальні набори даних, користувацькі постачальники даних та інші незадокументовані речі, що виглядає для мене занадто дивно.

Я поняття не маю, що означає ця форма "статична" чи "динамічна". Для мене всі форми оформлення замовлення будуються динамічно поверх шаблонів KnockoutJS, але ... коли я спробую "статичним" способом, я можу додати сюди входи (так це статична форма чи ні?).

Спочатку я намагаюся налагодити, чому спостережувані нокаути просто ігнорують мої поля під час розбору та надсилання даних. Я виявив, що в моїх полях порожній nameпараметр, але я не можу керувати способом виправити цю проблему. IMO він повинен бути переданий рендерінгу компонентів інтерфейсу через 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де визначені / створені спостереження Knockout.

Якось 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 виглядає дивно для мене)
  • Як надсилати значення полів, не пов'язаних з новими адресами? Я ніде не бачив подібної конфігурації. У моєму випадку я хотів би надіслати коментар до замовлення (textarea) та запит рахунку-фактури (прапорець). Обидва не повинні зберігатися як адреса, оскільки деякі користувачі можуть захотіти зберегти цю адресу для подальшого використання.
  • Чи є документація про "статичну" та "динамічну" форми чи деякі приклади / порівняння? Варто думати про це таким чином?

Додаткове екзистенційне питання:

  • Чому це так непослідовно? Чому я маю визначати тонни параметрів у файлах XML / PHP, тоді як Magento взагалі може лише вводити вхід, і тоді мені доводиться обробляти все самостійно?

3
Magento Devdocs недавно додав нові документи про використання компонентів інтерфейсу. Ми фактично пишемо цілий новий посібник ... але все ж є шляхи. Погляньте на сторінку devdocs.magento.com/guides/v2.1/ui_comp_guide/bk-ui_comps.html . На жаль, ми ще не доопрацювали теми з джерел даних, саме це, як здається, вам найбільше потрібно. Існує тема потоку конфігурації за допомогою компонентів інтерфейсу, яка може допомогти. Я працюю над тим, щоб знайти більше відповідей.
tanberry

Чому це повинен бути кошмар, додаючи просте поле на касі? Я просто не можу зрозуміти. І майже все так важко
вбивчий край

@slayerbleast Світ змінюється, відображення на стороні сервера вмирає. Тож інакше, не важче без будь-яких причин.
igloczek

Відповіді:


55

Я спробую відповісти на ваше питання.

  1. Ні . Це не правильний спосіб додавання спеціальних атрибутів до форми адреси доставки. Вам не потрібно редагувати new-customer-address.js. Дійсно, цей JS-файл містить перелік усіх попередньо визначених атрибутів адреси та відповідає відповідному інтерфейсу резервного інтерфейсу, \Magento\Quote\Api\Data\AddressInterfaceале Magento надає можливість передавати будь-які власні атрибути до бекенду без зміни компонентів бекенд / фронтенд .

    Згаданий компонент 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. :) Magento намагається охопити якомога більше випадків використання, які можуть бути значущими для продавців під час використання / налаштування Magento. Іноді це призводить до ситуації, коли деякі прості випадки використання стають складнішими.

Сподіваюся, це допомагає.

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

Добре ... Дозволяє написати якийсь код;)

  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. Додайте mixin, щоб змінити поведінку "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. Створіть своє ім’я_модуля / view / frontend / web / js / action / set-shipping-information-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. Створіть своє ім’я_модуля / 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 навіть навіть локальнаStorage checkout-dataне містить цих даних.
igloczek

Дивіться мою оновлену відповідь вище;)
aakimov

4
Офіційний документ на цю тему вже доступний! devdocs.magento.com/guides/v2.1/howdoi/checkout/…
Алекс

1
Чи потрібен додатковий крок для збереження значень проти замовлення?
Алекс Хадлі

Я думаю, що якщо у вас статична форма, краще вставити поле в LayoutProcessor через XML, як у цьому прикладі: devdocs.magento.com/guides/v2.1/howdoi/checkout/…
cjohansson

-1

На мій досвід, m2 використовує xml для визначення компонентів, таких як поля тощо. Це легше допомагає налагоджувати, інтерактивні з даними. У полі прихильників ви повинні спробувати замінити шаблони оформлення замовлення і додати там свої власні користувацькі поля. З KO допомагає вам працювати та зв'язувати дані з фронтену та бекенда


4
Це неправильна порада, b / c шаблони оформлення замовлення не містять і ніколи не повинні містити додані введення поля вручну. Ми повинні використовувати KO для візуалізації шаблонів у вибраних регіонах (все
створено

Чи можете ви поділитися прикладом додавання призначених для користувача ui-компонентів поля у передній частині?
mrtuvn

Як говорить @igloczek, це неправильна порада, оскільки шаблони оформлення замовлення ніколи не повинні містити поля введення вручну.
diazwatson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.