magento2结算页面-在地址表单中添加字段

7天成为Magento系统架构师,现在开始学习Magento全栈开发!

《Magento2.X企业级开发实战》

可以向默认结帐表单添加新字段,例如送货地址或账单地址表单。 为了说明这种能力,本主题描述了向送货地址表单添加一个字段。

要将自定义字段添加到结帐地址表单并在客户端访问其值:

  • 将字段添加到布局。
  • 添加JS mixin 修改数据提交。
  • 加载你的 mixin。
  • 将字段添加到地址模型。
  • 在服务器端访问自定义字段的值。

第 1 步:将字段添加到布局
送货地址和账单地址表格都是动态生成的。 要修改它们的布局,请为 \Magento\Checkout\Block\Checkout\LayoutProcessor::process 方法创建一个插件,并在模块的 di.xml文件中声明它。

以下代码段列举了将名为 Custom Attribute 的字段添加到收货地址表单的示例逻辑:

$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' => 'this is what the field is for',
        ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
       'required-entry' => true
    ],
    'options' => [],
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
    'value' => '' // value field is used to set a default value of the attribute
];

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

通过前面的例子,该字段被添加到'Magento_Checkout/js/model/new-customer-address.jscustomAttributes 属性中,这是一个 JavaScript 对象,列出所有预定义的地址属性并匹配相应的服务器端接口 \Magento\Quote \Api\Data\AddressInterface

customAttributes 属性旨在包含自定义 EAV 地址属性,并且与 \Magento\Quote\Model\Quote\Address\CustomAttributeListInterface::getAttributes 方法相关。上面的示例代码将在前端自动处理本地存储持久性。

或者,可以使用依赖项注入 (DI),而不是添加插件。要使用 DI,请将LayoutProcessor(它将自定义字段添加到地址表单类)添加到 <your_module_dir>/Block/Checkout/目录。该类必须实现 \Magento\Checkout\Block\Checkout\LayoutProcessorInterface接口。使用上面的代码示例作为 \Magento\Checkout\Block\Checkout\LayoutProcessorInterface::process()方法实现的示例。

要将LayoutProcessor 类添加到相应的处理器池,请在<your_module_dir>/etc/frontend/di.xml 中指定以下内容(其中%unique_name%和 %path\to\your\LayoutProcessor%必须由真实值替换)文件:

<type name="Magento\Checkout\Block\Onepage">
        <arguments>
            <argument name="layoutProcessors" xsi:type="array">
                <item name="%unique_name%" xsi:type="object">%path\to\your\LayoutProcessor%</item>
            </argument>
        </arguments>
</type>

第二步:添加JS mixin修改数据提交
在服务端添加一个JS mixin,改变负责数据提交的组件的行为。

在自定义模块中,将 mixin 定义为返回回调函数的单独 AMD 模块。 在 <your_module_dir>/view/frontend/web 目录中的任意位置添加 mixin 文件。 对 mixin 文件命名没有严格要求。

以下代码示例是修改 Magento_Checkout/js/action/set-shipping-information 行为的示例 mixin,该组件负责发货和计费结帐步骤之间的数据提交:

/*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'] = {};
            }

            var attribute = shippingAddress.customAttributes.find(
                function (element) {
                    return element.attribute_code === 'custom_field';
                }
            );

            shippingAddress['extension_attributes']['custom_field'] = attribute.value;
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});

在账单地址表单中添加字段时,必须修改 Magento_Checkout/js/action/place-order 或 Magento_Checkout/js/action/set-payment-information 组件的行为,具体取决于何时需要自定义字段值 传递给服务器端。

要查看修改这些组件之一的混合示例,请参阅 Magento_CheckoutAgreements 模块中的 place-order-mixin.js


第 3 步:加载你的 mixin
通过将 requirejs-config.js添加到<YourModule_dir>/view/frontend/目录,告诉 Magento 为相应的 JS 组件加载 mixin。

下面的代码示例显示了一个使用之前添加的示例 mixin 的示例:

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                '<YourNamespace_YourModule>/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

第 4 步:将字段添加到地址模型
要将字段添加到服务器端的地址模型,请在 <YourModule_dir>/etc/ 目录中添加extension_attributes.xml 文件。

以下代码是 extension_attributes.xml文件的示例:

<?xml version="1.0"?>

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

运行 setup:di:compile 命令时清除generated/code目录。 新的 getter 和 setter 方法将添加到生成的/code/Magento/Quote/Api/Data/AddressExtension.php 文件中。


第五步:在服务器端访问自定义字段的值
如果完成了前面部分中描述的所有步骤,Magento 将生成包含自定义属性的界面,可以访问字段值。

可以通过创建 Magento/Quote/Api/Data/AddressInterface.php接口的实例来设置/获取这些属性值。

<?php

// ... //

use Magento\Checkout\Api\Data\ShippingInformationInterface;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;

class MyBlock extends Template {

    /**
     * @var ShippingInformationInterface
     */
    private $_addressInformation;

    /**
     * @param Context $context
     * @param ShippingInformationInterface $addressInformation
     * @param array $data
     */
    public function __construct(
        Context $context,
        ShippingInformationInterface $addressInformation,
        array $data = []
    ) {
        $this->_addressInformation = $addressInformation;
        parent::__construct($context, $data);
    }

    /**
     * Get custom Shipping Charge
     *
     * @return String
     */
    public function getShippingCharge()
    {
        $extAttributes = $this->_addressInformation->getExtensionAttributes();
        return $extAttributes->getCustomField(); //get custom attribute data.
    }
}

最后清除缓存:

php bin/magento s:up
php bin/magento s:d:c
chmod -R 777 /var/www/html/magento
如无特殊说明或标注,任何个人或组织,复制、转载、采集本站内容请注明:
本文来源于:【Magento中文网】,并添加本文地址链接。
如未按上述操作复制或转载,本站有权追究法律责任。
若本站内容侵犯了原著者的合法权益,可联系我们进行处理。