UI-Form에 필드가 있는 Fieldset을 추가하는 쉬운 방법
게시 됨: 2016-08-23이 기사에서는 제품 편집 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, '공급업체_제품', __디렉터리__ ); ?>
컴포저 파일 생성(모듈을 전송하려는 경우) app/code/Vendor/Module/composer.json :
{ "이름": "공급업체/모듈 제품", "설명": "해당 사항 없음", "유형": "magento2 모듈", "버전": "1.0.0", "라이센스": [ "OSL-3.0", "AFL-3.0" ], "자동 로드": { "파일": [ "등록.php" ], "psr-4": { "공급업체\\제품\\": "" } } }
이제 Magento_Catalog 모듈의 종속성을 사용하여 모듈의 기본 XML 파일 app/code/Vendor/Product/etc/module.xml을 만듭니다. 모달 창이 해당 형식에 추가되기 때문입니다.
<?xml 버전="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <모듈 이름="Vendor_Product" setup_version="1.0.0"> <순서> <모듈 이름="Magento_Catalog"/> </순서> </모듈> </구성>
루트 Magento 디렉토리에 bin/magento module:enable Vendor_Product 및 bin/magento setup:upgrade를 입력하여 모듈을 활성화합니다.
그런 다음 모듈의 콘텐츠를 추가합니다. 추가할 UI 형식 메타데이터 및 가상 유형입니다.
app/code/Vendor/Product/etc/adminhtml/di.xml 파일을 만듭니다. 우리는 내부에 수정자를 배치할 것입니다:
<?xml 버전="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> </항목> </인수> </인수> </가상 유형> </구성>
수정자는 데이터 추가 및 요소 및 UI 형식 구성 요소에 대한 일부 조작을 담당합니다. 수정자의 인터페이스에서 가져온 두 가지 주요 메서드가 있습니다(항상 표시되어야 함).
<?php /** * Copyright 2016 마젠토. 판권 소유. * 라이선스에 대한 자세한 내용은 COPYING.txt를 참조하십시오. */ 네임스페이스 Magento\Ui\DataProvider\Modifier; /** * 클래스 수정자 인터페이스 */ 인터페이스 수정자인터페이스 { /** * @param 배열 $data * @return 배열 */ 공개 함수 modifyData(배열 $data); /** * @param 배열 $meta * @return 배열 */ 공개 함수 modifyMeta(배열 $meta); } ?>
이 예제에서는 modifyMeta 메서드를 사용할 것입니다. modifyData 메서드는 다음 기사에서 설명합니다.
이제 제품 편집 페이지에 대한 사용자 정의 필드 세트가 있는 수정자 파일(app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php)을 만들고 필드로 채우십시오.
<?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 = '커스텀_필드셋'; const CUSTOM_FIELDSET_CONTENT = '맞춤_필드세트_콘텐츠'; const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header'; // 필드 이름 const FIELD_NAME_TEXT = '예시_텍스트_필드'; const FIELD_NAME_SELECT = 'example_select_field'; const FIELD_NAME_MULTISELECT = 'example_multiselect_field'; /** * @var \Magento\Catalog\Model\Locator\LocatorInterface */ 보호된 $locator; /** * @var 어레이매니저 */ 보호된 $arrayManager; /** * @var URL인터페이스 */ 보호된 $urlBuilder; /** * @var 배열 */ 보호된 $메타 = []; /** * @param LocatorInterface $locator * @param ArrayManager $arrayManager * @param UrlInterface $urlBuilder */ 공개 함수 __construct( 로케이터 인터페이스 $ 로케이터, 어레이매니저 $배열매니저, URL 인터페이스 $urlBuilder ) { $this->locator = $locator; $this->arrayManager = $arrayManager; $this->urlBuilder = $urlBuilder; } /** * 데이터 수정자는 이 예에서 아무 작업도 수행하지 않습니다. * * @param 배열 $data * @return 배열 */ 공개 함수 modifyData(배열 $data) { $ 데이터 반환; } /** * 메타 데이터 수정자: 필드 세트 추가 * * @param 배열 $meta * @return 배열 */ 공개 함수 modifyMeta(배열 $meta) { $this->meta = $meta; $this->addCustomFieldset(); $this->메타를 반환합니다. } /** * 기존 메타 데이터를 우리의 메타 데이터와 병합합니다(덮어쓰지 마십시오!) * * @반환 무효 */ 보호된 함수 addCustomFieldset() { $this->meta = array_merge_recursive( $this->메타, [ static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(), ] ); } /** * 우리의 fieldset 구성을 선언하십시오 * * @return 배열 */ 보호된 함수 getFieldsetConfig() { 반품 [ '인수' => [ '데이터' => [ '구성' => [ '레이블' => __('필드셋 제목'), 'componentType' => Fieldset::NAME, 'dataScope' => static::DATA_SCOPE_PRODUCT, // 제품 데이터에 데이터 저장 '제공자' => static::DATA_SCOPE_PRODUCT . '_data_source', 'ns' => 정적::FORM_NAME, '축소 가능' => 사실, '정렬 순서' => 10, '열림' => 사실, ], ], ], '아이들' => [ static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10), static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20), static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30), static::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40), ], ]; } /** * 헤더 컨테이너에 대한 구성 가져오기 * * @param int $sortOrder * @return 배열 */ 보호된 함수 getHeaderContainerConfig($sortOrder) { 반품 [ '인수' => [ '데이터' => [ '구성' => [ '레이블' => null, 'formElement' => 컨테이너::이름, 'componentType' => 컨테이너::이름, '템플릿' => 'ui/form/components/complex', 'sortOrder' => $sortOrder, 'content' => __('여기에 아무 텍스트나 쓸 수 있습니다.'), ], ], ], '어린이' => [], ]; } /** * 예제 텍스트 필드 구성 * * @param $sortOrder * @return 배열 */ 보호된 함수 getTextFieldConfig($sortOrder) { 반품 [ '인수' => [ '데이터' => [ '구성' => [ 'label' => __('예제 텍스트 필드'), 'formElement' => 필드::이름, 'componentType' => 입력::이름, 'dataScope' => 정적::FIELD_NAME_TEXT, 'dataType' => 번호::이름, 'sortOrder' => $sortOrder, ], ], ], ]; } /** * 선택 필드 구성의 예 * * @param $sortOrder * @return 배열 */ 보호된 함수 getSelectFieldConfig($sortOrder) { 반품 [ '인수' => [ '데이터' => [ '구성' => [ 'label' => __('옵션 선택'), 'componentType' => 필드::이름, 'formElement' => 선택::이름, 'dataScope' => 정적::FIELD_NAME_SELECT, 'dataType' => 텍스트::이름, 'sortOrder' => $sortOrder, '옵션' => $this->_getOptions(), '보이는' => 사실, '비활성화' => 거짓, ], ], ], ]; } /** * 다중 선택 필드 구성의 예 * * @param $sortOrder * @return 배열 */ 보호된 함수 getMultiSelectFieldConfig($sortOrder) { 반품 [ '인수' => [ '데이터' => [ '구성' => [ 'label' => __('옵션 다중 선택'), 'componentType' => 필드::이름, 'formElement' => 다중 선택::이름, 'dataScope' => 정적::FIELD_NAME_MULTISELECT, 'dataType' => 텍스트::이름, 'sortOrder' => $sortOrder, '옵션' => $this->_getOptions(), '보이는' => 사실, '비활성화' => 거짓, ], ], ], ]; } /** * 예제 옵션을 옵션 배열로 가져오기: * [ * 레이블 => 문자열, * 값 => option_id * ] * * @return 배열 */ 보호된 함수 _getOptions() { $옵션 = [ 1 => [ '레이블' => __('옵션 1'), '값' => 1 ], 2 => [ '레이블' => __('옵션 2'), '값' => 2 ], 3 => [ '레이블' => __('옵션 3'), '값' => 3 ], ]; $options를 반환합니다. } } ?>
이 예에서는 기존 UI 형식 메타 데이터를 가져와 새 데이터와 병합(다시 작성하지 않음!)해야 합니다.
<?php /** * 기존 메타 데이터를 우리의 메타 데이터와 병합합니다(덮어쓰지 마십시오!) * * @반환 무효 */ 보호된 함수 addCustomFieldset() { $this->meta = array_merge_recursive( $this->메타, [ static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(), ] ); } ?>
완료되면 getFieldsetConfig 메소드에 새 필드 세트를 추가합니다.
<?php /** * 우리의 fieldset 구성을 선언하십시오 * * @return 배열 */ 보호된 함수 getFieldsetConfig() { 반품 [ '인수' => [ '데이터' => [ '구성' => [ '레이블' => __('필드셋 제목'), 'componentType' => Fieldset::NAME, 'dataScope' => static::DATA_SCOPE_PRODUCT, // 제품 데이터에 데이터 저장 '제공자' => static::DATA_SCOPE_PRODUCT . '_data_source', 'ns' => 정적::FORM_NAME, '축소 가능' => 사실, '정렬 순서' => 10, '열림' => 사실, ], ], ], '아이들' => [ static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10), static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20), static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30), static::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40), ], ]; } ?>
추상 제품 UI 형식 수정자에서 상속하고 해당 네임스페이스와 데이터를 공급자로 사용합니다. 'provider' => static::DATA_SCOPE_PRODUCT . '_data_source'(여기서 DATA_SCOPE_PRODUCT는 'data.product' 라인임).
componentType 옵션은 주요 옵션 중 하나이며 구성 요소 유형을 담당합니다. 접을 수 있는 옵션은 필드 집합을 접고 확장하는 역할을 합니다. 그리고 열기 옵션은 양식을 그리는 동안 기본적으로 필드 세트를 열 것인지 여부를 정의합니다.
그런 다음 결과적으로 getHeaderContainerConfig 메소드의 필드 세트에 헤더를 추가하고 필드의 3가지 예(텍스트, 선택 및 다중 선택)를 추가합니다. 그러나 제품과 양식은 modifyData 메서드에 추가할 때까지 데이터를 수신하지 않습니다. 그러나 저장하는 동안 데이터를 전송하고 가로챌 수 있는 기능이 있습니다.
양식이 어떻게 보이는지 봅시다.
데이터 저장은 메인 실행 메소드의 제품 컨트롤러 파일 vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php 내에서 발생합니다. 모든 것이 올바른 방식으로 수행되면 이 메서드의 입력 데이터에 데이터가 올바르게 표시됩니다.
제품에 처음부터 해당 속성이 없으면 수동으로 저장해야 합니다. 관찰자에서 이 작업을 수행할 수 있습니다.
먼저 app/code/Vendor/Product/etc/adminhtml/events.xml 파일에서 선언합니다(프론트 엔드에 양식이 없기 때문에 adminhtml 범위를 사용합니다).
<?xml 버전="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <이벤트 이름="catalog_product_save_after"> <관찰자 이름="save_example_data" instance="Vendor\Product\Observer\ProductSaveAfter" /> </이벤트> </구성>
그런 다음 instance 속성에서 가리킨 관찰자의 클래스를 만듭니다. 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(); if (!$product) { 반품; } $exampleTextField = $product->getData(CustomFieldset::FIELD_NAME_TEXT); $exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT); $exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT); // 여기에서 데이터 조작 } } ?>
관찰자의 데이터:
이제 관찰자로부터 자신의 모델을 호출하고 데이터를 저장하거나 원하는 대로 수정할 수 있습니다.
조심하세요! 모델 저장이 제품 저장과 연결되면 재귀로 이어질 수 있습니다.