วิธีง่ายๆ ในการเพิ่ม Fieldset พร้อมฟิลด์ใน UI-Form
เผยแพร่แล้ว: 2016-08-23ในบทความนี้ เราจะสร้างโมดูลอย่างง่ายที่จะเพิ่ม fieldset พร้อมฟิลด์ในแบบฟอร์ม UI การแก้ไขผลิตภัณฑ์ นอกจากนี้ เราจะสร้างผู้สังเกตการณ์เพื่อสกัดกั้นข้อมูลนี้ในระหว่างการบันทึกผลิตภัณฑ์
ขั้นแรก เราต้องสร้างโมดูล Vendor_Product:
1. สร้างไดเร็กทอรี app/code/Vendor/Product
2. สร้างไฟล์ลงทะเบียน app/code/Vendor/Product/registration.php โดยมีเนื้อหาดังนี้
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'ผู้ขาย_ผลิตภัณฑ์'
__DIR__
);
?>สร้างไฟล์ผู้แต่ง (หากคุณวางแผนที่จะโอนโมดูล) app/code/Vendor/Module/composer.json :
{
"name": "ผู้จำหน่าย/โมดูล-ผลิตภัณฑ์",
"description": "ไม่มี",
"type": "magento2-module",
"เวอร์ชัน": "1.0.0",
"ใบอนุญาต": [
"OSL-3.0",
"แอฟ-3.0"
],
"โหลดอัตโนมัติ": {
"ไฟล์": [
"การลงทะเบียน.php"
],
"psr-4": {
"ผู้ขาย\\Product\\": ""
}
}
}ตอนนี้ ให้สร้าง app/code/Vendor/Product/etc/module.xml ไฟล์ XML หลักของโมดูลด้วยการพึ่งพาจากโมดูล Magento_Catalog เนื่องจากหน้าต่างโมดอลของเราจะถูกเพิ่มลงในแบบฟอร์ม:
<?xml version="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_Product" setup_version="1.0.0">
<ลำดับ>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>เปิดใช้งานโมดูลโดยป้อนข้อมูลต่อไปนี้: bin/magento module:enable Vendor_Product และ bin/magento setup:upgrade ในไดเร็กทอรี root Magento
จากนั้น เพิ่มเนื้อหาของโมดูล: meta-data ของฟอร์ม UI และประเภทเสมือนสำหรับการเพิ่ม
สร้างไฟล์ app/code/Vendor/Product/etc/adminhtml/di.xml. เราจะวางโมดิฟายเออร์ไว้ข้างใน:
<?xml version="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
<อาร์กิวเมนต์>
<argument name="modifiers" xsi:type="array">
<item name="custom-fieldset" xsi:type="array">
<item name="class" xsi:type="string">Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</อาร์กิวเมนต์>
</arguments>
</virtualType>
</config>ตัวแก้ไขมีหน้าที่ในการเพิ่มข้อมูลและการปรับแต่งบางอย่างกับองค์ประกอบและส่วนประกอบรูปแบบ UI มี 2 วิธีหลักที่มาจากอินเทอร์เฟซของตัวปรับแต่ง (ควรมีอยู่เสมอ):
<?php
/**
* ลิขสิทธิ์ 2016 Magento สงวนลิขสิทธิ์.
* ดู COPYING.txt สำหรับรายละเอียดใบอนุญาต
*/
เนมสเปซ Magento\Ui\DataProvider\Modifier;
/**
* Class ModifierInterface
*/
ตัวแก้ไขส่วนต่อประสานอินเทอร์เฟซ
{
/**
* @param array $data
* @return อาร์เรย์
*/
ฟังก์ชั่นสาธารณะ modifiedData (อาร์เรย์ $ data);
/**
* @param array $meta
* @return อาร์เรย์
*/
ฟังก์ชั่นสาธารณะ modifiedMeta (อาร์เรย์ $ meta);
}
?>เราจะใช้เมธอด modifiedMeta ในตัวอย่างนี้ วิธี modifiedData จะอธิบายในบทความถัดไป
ตอนนี้ สร้างไฟล์ตัวแก้ไข (app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php) ด้วย fieldset ที่กำหนดเองสำหรับหน้าแก้ไขผลิตภัณฑ์และกรอกข้อมูลด้วยฟิลด์:
<?php
เนมสเปซ Vendor\Product\Ui\DataProvider\Product\Form\Modifier;
ใช้ Magento\Catalog\Model\Locator\LocatorInterface;
ใช้ Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
ใช้ Magento\Framework\Stdlib\ArrayManager;
ใช้ Magento\Framework\UrlInterface;
ใช้ Magento\Ui\Component\Container;
ใช้ Magento\Ui\Component\Form\Fieldset;
ใช้ Magento\Ui\Component\Form\Element\DataType\Number;
ใช้ Magento\Ui\Component\Form\Element\DataType\Text;
ใช้ Magento\Ui\Component\Form\Element\Input;
ใช้ Magento\Ui\Component\Form\Element\Select;
ใช้ Magento\Ui\Component\Form\Element\MultiSelect;
ใช้ Magento\Ui\Component\Form\Field;
คลาส CustomFieldset ขยาย AbstractModifier
{
// ดัชนีส่วนประกอบ
const CUSTOM_FIELDSET_INDEX = 'custom_fieldset';
const CUSTOM_FIELDSET_CONTENT = 'custom_fieldset_content';
const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header';
// ชื่อช่อง
const FIELD_NAME_TEXT = 'example_text_field';
const FIELD_NAME_SELECT = 'example_select_field';
const FIELD_NAME_MULTISELECT = 'example_multiselect_field';
/**
* @var \Magento\Catalog\Model\Locator\LocatorInterface
*/
ป้องกันตัวระบุตำแหน่ง $;
/**
* @var ArrayManager
*/
ป้องกัน $ arrayManager;
/**
* @var UrlInterface
*/
ป้องกัน $urlBuilder;
/**
* @var array
*/
ป้องกัน $meta = [];
/**
* @param LocatorInterface $locator
* @param ArrayManager $arrayManager
* @param UrlInterface $ urlBuilder
*/
ฟังก์ชั่นสาธารณะ __construct(
LocatorInterface $ ตัวระบุตำแหน่ง,
ArrayManager $arrayManager,
UrlInterface $urlBuilder
) {
$this->locator = $locator;
$this->arrayManager = $arrayManager;
$this->urlBuilder = $urlBuilder;
}
/**
* ตัวแก้ไขข้อมูล ไม่ทำอะไรเลยในตัวอย่างของเรา
*
* @param array $data
* @return อาร์เรย์
*/
ฟังก์ชั่นสาธารณะ modifiedData (อาร์เรย์ $ data)
{
ส่งคืนข้อมูล $;
}
/**
* ตัวแก้ไขข้อมูลเมตา: เพิ่ม fieldset ของเรา
*
* @param array $meta
* @return อาร์เรย์
*/
ฟังก์ชั่นสาธารณะ modifiedMeta (อาร์เรย์ $ meta)
{
$this->meta = $meta;
$this->addCustomFieldset();
คืนค่า $this->meta;
}
/**
* รวม meta-data ที่มีอยู่กับ meta-data ของเรา (อย่าเขียนทับ!)
*
* @return เป็นโมฆะ
*/
ฟังก์ชันที่ได้รับการป้องกัน addCustomFieldset()
{
$this->meta = array_merge_recursive(
$this->เมตา,
[
คงที่::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(),
]
);
}
/**
* ประกาศ fieldset config . ของเรา
*
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน getFieldsetConfig()
{
กลับ [
'ข้อโต้แย้ง' => [
'ข้อมูล' => [
'config' => [
'label' => __('ชื่อชุดฟิลด์'),
'componentType' => Fieldset::NAME,
'dataScope' => static::DATA_SCOPE_PRODUCT, // บันทึกข้อมูลใน data data
'provider' => static::DATA_SCOPE_PRODUCT . '_แหล่งข้อมูล',
'ns' => คงที่::FORM_NAME,
'พับได้' => จริง
'sortOrder' => 10,
'เปิด' => จริง
],
],
],
'ลูก' => [
คงที่::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10),
คงที่::FIELD_NAME_TEXT => $this->getTextFieldConfig(20),
คงที่::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30),
คงที่::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40),
],
];
}
/**
* รับการกำหนดค่าสำหรับคอนเทนเนอร์ส่วนหัว
*
* @param int $sortOrder
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน getHeaderContainerConfig($sortOrder)
{
กลับ [
'ข้อโต้แย้ง' => [
'ข้อมูล' => [
'config' => [
'label' => null,
'formElement' => คอนเทนเนอร์::NAME,
'componentType' => คอนเทนเนอร์::NAME,
'แม่แบบ' => 'ui/แบบฟอร์ม/ส่วนประกอบ/ซับซ้อน',
'sortOrder' => $sortOrder,
'content' => __('คุณสามารถเขียนข้อความได้ที่นี่'),
],
],
],
'เด็ก' => [],
];
}
/**
* ตัวอย่างฟิลด์ข้อความ config
*
* @param $sortOrder
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน getTextFieldConfig($sortOrder)
{
กลับ [
'ข้อโต้แย้ง' => [
'ข้อมูล' => [
'config' => [
'label' => __('ตัวอย่างฟิลด์ข้อความ'),
'formElement' => ฟิลด์::NAME,
'componentType' => อินพุต::NAME,
'dataScope' => คงที่::FIELD_NAME_TEXT,
'dataType' => Number::NAME,
'sortOrder' => $sortOrder,
],
],
],
];
}
/**
* ตัวอย่างเลือกฟิลด์ config
*
* @param $sortOrder
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน getSelectFieldConfig($sortOrder)
{
กลับ [
'ข้อโต้แย้ง' => [
'ข้อมูล' => [
'config' => [
'label' => __('Options Select'),
'componentType' => ฟิลด์::NAME,
'formElement' => เลือก::NAME,
'dataScope' => คงที่::FIELD_NAME_SELECT,
'dataType' => ข้อความ::NAME,
'sortOrder' => $sortOrder,
'options' => $this->_getOptions(),
'มองเห็นได้' => จริง
'ปิดการใช้งาน' => เท็จ
],
],
],
];
}
/**
* ตัวอย่างการกำหนดค่าฟิลด์แบบเลือกได้หลายรายการ
*
* @param $sortOrder
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน getMultiSelectFieldConfig($sortOrder)
{
กลับ [
'ข้อโต้แย้ง' => [
'ข้อมูล' => [
'config' => [
'label' => __('ตัวเลือกหลายตัวเลือก'),
'componentType' => ฟิลด์::NAME,
'formElement' => MultiSelect::NAME,
'dataScope' => คงที่::FIELD_NAME_MULTISELECT,
'dataType' => ข้อความ::NAME,
'sortOrder' => $sortOrder,
'options' => $this->_getOptions(),
'มองเห็นได้' => จริง
'ปิดการใช้งาน' => เท็จ
],
],
],
];
}
/**
* รับตัวเลือกตัวอย่างเป็นอาร์เรย์ตัวเลือก:
* [
* label => สตริง
* ค่า => option_id
* ]
*
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน _getOptions()
{
ตัวเลือก $ = [
1 => [
'label' => __('ตัวเลือก 1'),
'value' => 1
],
2 => [
'label' => __('ตัวเลือก 2'),
'ค่า' => 2
],
3 => [
'label' => __('ตัวเลือก 3'),
'value' => 3
],
];
ส่งคืนตัวเลือก $;
}
}
?>
ในตัวอย่างนี้ เราจำเป็นต้องใช้ข้อมูลเมตาของฟอร์ม UI ที่มีอยู่แล้วรวมเข้าด้วยกัน (ไม่เขียนซ้ำ!) กับข้อมูลใหม่ของเรา:

<?php
/**
* รวม meta-data ที่มีอยู่กับ meta-data ของเรา (อย่าเขียนทับ!)
*
* @return เป็นโมฆะ
*/
ฟังก์ชันที่ได้รับการป้องกัน addCustomFieldset()
{
$this->meta = array_merge_recursive(
$this->เมตา,
[
คงที่::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(),
]
);
}
?>เมื่อเสร็จแล้ว เพิ่ม fieldset ใหม่ให้กับเมธอด getFieldsetConfig:
<?php
/**
* ประกาศ fieldset config . ของเรา
*
* @return อาร์เรย์
*/
ฟังก์ชันที่ได้รับการป้องกัน getFieldsetConfig()
{
กลับ [
'ข้อโต้แย้ง' => [
'ข้อมูล' => [
'config' => [
'label' => __('ชื่อชุดฟิลด์'),
'componentType' => Fieldset::NAME,
'dataScope' => static::DATA_SCOPE_PRODUCT, // บันทึกข้อมูลใน data data
'provider' => static::DATA_SCOPE_PRODUCT . '_แหล่งข้อมูล',
'ns' => คงที่::FORM_NAME,
'พับได้' => จริง
'sortOrder' => 10,
'เปิด' => จริง
],
],
],
'ลูก' => [
คงที่::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10),
คงที่::FIELD_NAME_TEXT => $this->getTextFieldConfig(20),
คงที่::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30),
คงที่::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40),
],
];
}
?>เราสืบทอดจากตัวแก้ไขฟอร์ม UI ของผลิตภัณฑ์นามธรรม และใช้เนมสเปซและข้อมูลเป็นผู้ให้บริการ: 'provider' => static::DATA_SCOPE_PRODUCT '_data_source' (โดยที่ DATA_SCOPE_PRODUCT คือบรรทัด 'data.product')
ตัวเลือก componentType เป็นหนึ่งในตัวเลือกหลักและรับผิดชอบประเภทส่วนประกอบ ตัวเลือกที่ยุบได้มีหน้าที่ในการยุบและขยายชุดข้อมูลของเรา และตัวเลือกเปิดจะกำหนดว่าชุดฟิลด์จะเปิดขึ้นตามค่าเริ่มต้นในระหว่างการวาดแบบฟอร์มหรือไม่
จากนั้น เราจึงเพิ่มส่วนหัวให้กับชุดฟิลด์ของเราในเมธอด getHeaderContainerConfig และตัวอย่างฟิลด์ 3 ตัวอย่าง ได้แก่ ข้อความ เลือก และการเลือกหลายรายการ อย่างไรก็ตาม ผลิตภัณฑ์และแบบฟอร์มของเราจะไม่ได้รับข้อมูลจนกว่าเราจะเพิ่มลงในวิธี modifiedData แต่เรามีความสามารถในการส่งและสกัดกั้นข้อมูลในระหว่างการบันทึก
มาดูกันว่ารูปร่างหน้าตาเป็นอย่างไร:
การบันทึกข้อมูลเกิดขึ้นภายในไฟล์ควบคุมผลิตภัณฑ์ vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php ในวิธีการดำเนินการหลัก หากทำทุกอย่างถูกต้องแล้ว ข้อมูลของเราจะแสดงอย่างถูกต้องในข้อมูลที่ป้อนของวิธีนี้:
หมายเหตุ หากผลิตภัณฑ์ของคุณไม่มีแอตทริบิวต์เหล่านั้นตั้งแต่เริ่มต้น คุณควรบันทึกด้วยตนเอง คุณสามารถทำได้ในผู้สังเกตการณ์
ขั้นแรก ประกาศในไฟล์ app/code/Vendor/Product/etc/adminhtml/events.xml (เราใช้ขอบเขต adminhtml เนื่องจากไม่มีแบบฟอร์มที่ส่วนหน้า):
<?xml version="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_product_save_after">
<observer name="save_example_data" instance="Vendor\Product\Observer\ProductSaveAfter" />
</event>
</config>จากนั้น สร้างคลาสของผู้สังเกตการณ์ที่เราชี้ไปที่แอตทริบิวต์อินสแตนซ์ – app/code/Vendor/Product/Observer/ProductSaveAfter.php:
<?php
เนมสเปซ Vendor\Product\Observer;
ใช้ \Magento\Framework\Event\ObserverInterface;
ใช้ \Magento\Framework\Event\Observer เป็น EventObserver;
ใช้ Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset;
คลาส ProductSaveAfter ใช้ ObserverInterface
{
/**
* @param EventObserver $ ผู้สังเกตการณ์
*/
เรียกใช้ฟังก์ชันสาธารณะ (\Magento\Framework\Event\Observer $observer)
{
/** @var \Magento\Catalog\Model\Product $product */
$product = $observer->getEvent()->getProduct();
ถ้า (!$ ผลิตภัณฑ์) {
กลับ;
}
$exampleTextField = $product->getData(CustomFieldset::FIELD_NAME_TEXT); $exampleTextField = $product->getData(CustomFieldset::FIELD_NAME_TEXT);
$exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT); $exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT);
$exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT); $exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT);
// จัดการข้อมูลที่นี่
}
}
?>ข้อมูลในผู้สังเกต:

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