Magento 2 REST API의 DynamicRows (또는 연관 배열)

Oct 02 2020

모바일 애플리케이션에 Magento 2 REST API를 사용하고 있습니다. 나는 약간의 복잡성에 직면하여 당신의 도움이 필요합니다.

UI 양식에 두 개의 필드가있는 DynamicRows 구성 요소가 있는데 필드 이름은 localization 입니다.

<container name="localization" sortOrder="9" >
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/dynamic-rows/dynamic-rows</item>
            <item name="template" xsi:type="string">ui/dynamic-rows/templates/default</item>
            <item name="componentType" xsi:type="string">dynamicRows</item>
            <item name="label" xsi:type="string" translate="true">Data</item>
            <item name="recordTemplate" xsi:type="string">record</item>
            <item name="addButtonLabel" xsi:type="string">Add Parameter</item>
            <item name="deleteProperty" xsi:type="boolean">false</item>
            <item name="enabled" xsi:type="boolean">false</item>
        </item>
    </argument>

    <container name="record">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true" />
                <item name="component" xsi:type="string" translate="true">Magento_Ui/js/dynamic-rows/record</item>
                <item name="isTemplate" xsi:type="boolean">true</item>
                <item name="is_collection" xsi:type="boolean">true</item>
                <item name="showFallbackReset" xsi:type="boolean">false</item>
            </item>
        </argument>

        <field name="option_label">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Parameter</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">option_label</item>
                    <item name="showFallbackReset" xsi:type="boolean">false</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                    <item name="sortOrder" xsi:type="string">10</item>
                </item>
            </argument>
        </field>

        <field name="option_value">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Value</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">option_value</item>
                    <item name="showFallbackReset" xsi:type="boolean">false</item>
                    <item name="additionalClasses" xsi:type="array">
                        <item name="cirklestudio_color_picker" xsi:type="boolean">true</item>
                    </item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                    <item name="sortOrder" xsi:type="string">20</item>
                </item>
            </argument>
        </field>

        <actionDelete>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="componentType" xsi:type="string">actionDelete</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="fit" xsi:type="boolean">false</item>
                    <item name="label" xsi:type="string" />
                    <item name="additionalClasses" xsi:type="string">data-grid-actions-cell</item>
                    <item name="template" xsi:type="string">Magento_Backend/dynamic-rows/cells/action-delete</item>
                </item>
            </argument>
        </actionDelete>
        
    </container>

</container>

DynamicRows의 출력은 다음과 같습니다.

Array
(
    [0] => Array
        (
            [row_id] => 
            [option_label] => tmp_dir
            [option_value] => temp
            [position] => 1
            [record_id] => 0
            [initialize] => true
        )

    [1] => Array
        (
            [record_id] => 1
            [row_id] => 
            [option_label] => main_dir
            [option_value] => APD
            [position] => 2
            [initialize] => true
        )
)

인터페이스에서 getLocalization () 메서드를 선언했습니다.

/**
 * Return localized parameters for the application
 *
 * @return mixed[]
 */
public function getLocalization();

그런 다음 방법을 구현했습니다.

/**
 * @inheritdoc
 */
public function getLocalization()
{
    // Unserialize array
    $data = $this->_getData('localization') ? unserialize($this->_getData('localization')) : ""; $output = [];
    foreach ($data as $param) {
        $output[$param['option_label']] =  $param['option_value']; } return $output;
}

위의 방법에서는 요구 사항에 따라 DynamicRows 배열 출력을 수정했습니다.

Array
(
    [tmp_dir] => temp
    [main_dir] => APD
)

REST API 끝점에 도달하면 다음과 같은 응답이 표시됩니다.

<localization>
    <item>temp</item>
    <item>APD</item>
</localization>

다음 응답을 기대하지만

<localization>
    <tmp_dir>temp</tmp_dir>
    <main_dir>APD</main_dir>
</localization>

여러 기사를 검색했지만 내 요구 사항에 맞는 최상의 답변을 찾지 못했습니다.

질문 : DynamicRows 데이터가 항상 동일하지는 않습니다. 다른 레코드에 option_label 및 option_value 가 다른 필드가 두 개 이상있을 수 있다는 점을 염두에두고 예상 결과를 얻으려면 어떻게해야 합니까?

답변

4 HerveTribouilloy Oct 03 2020 at 19:52

나는 다음 사항에 도달했습니다.

나는 당신이 그것으로부터 더 많은 것을 얻기 위해 고군분투 할 것이라고 생각합니다. 기본적으로 항목 키는 Magento 핵심 구문 분석 방법에서 제공되므로 결과가 xml로 제공됩니다.

내 단계를 자세히 설명 할 수는 있지만 2 개 이상의 인터페이스와 약간의 구문 분석이 필요합니다.이 출력이 타협 할 수 있는지 알려주십시오.

조셉의 대답은 저보다 간단합니다 (더 우아합니다). 그러나 아래는 내 솔루션의 핵심입니다. 또한 직접 사용해 볼 수 있도록 bitbucket 저장소에 대한 링크를 추가했습니다.https://bitbucket.org/magstaging/apiparser/src/master/

    $output = []; foreach ($data as $param) { $output[$param['option_label']] = $param['option_value'];
            }
    
            return $this->parsedDataInterfaceFactory->create([ 'itemsData' => $output
            ]);


class ParsedResult implements ParsedDataInterface
{
    /**
     * @var \Mbs\Calculator\Api\Data\ParsedDataItemInterface[]
     */
    private $items = []; /** * OperationResult constructor. * @param array $itemsData
     * @param \Mbs\Calculator\Api\Data\ParsedDataItemInterfaceFactory $dataItemInterfaceFactory */ public function __construct( $itemsData,
        \Mbs\Calculator\Api\Data\ParsedDataItemInterfaceFactory $dataItemInterfaceFactory ) { foreach ($itemsData as $itemLabel => $itemValue) {
            $this->items[] = $dataItemInterfaceFactory->create([
                'label' => $itemLabel, 'value' => $itemValue
            ]);
        }
    }

    /**
     * @return \Mbs\Calculator\Api\Data\ParsedDataItemInterface[]
     */
    public function getLocalization()
    {
        return $this->items; } } class Item implements ParsedDataItemInterface { /** * @var string */ private $label;

    /**
     * @var string
     */
    private $value; /** * @inheritdoc */ public function __construct( string $label,
        string $value ) { $this->label = $label; $this->value = $value; } /** * @inheritdoc */ public function getLabel() { return $this->label;
    }

    /**
     * @inheritdoc
     */
    public function getValue()
    {
        return $this->value;
    }
}
2 JosephatSwiftOtter Oct 03 2020 at 20:38

원하는 결과를 얻으려면 더 많은 클래스를 만들어야합니다.

이 경우 getLocalization다음과 같은 클래스의 인스턴스를 반환해야합니다.

/**
 * @return \MyCompany\MyModule\Model\Localization[]
 **/
public function getLocalization(): array
{
    // Unserialize array
    $data = $this->_getData('localization') ? unserialize($this->_getData('localization')) : ""; return array_map(function($option) {
        return $this->localizationFactory->create([ 'label' => $param['option_label'],
            'value' => $param['option_value']
        ]);
    });
}

어디에 $this->localizationFactory: \MyCompany\MyModule\Model\LocalizationFactory.

LocalizationFactory 두 가지 방법이 있어야합니다.

  • getLabel
  • getValue

이것은 장황 해 보일 수 있습니다. 그러나이 경로를 통해 출력을 100 % 제어 할 수 있습니다. 테스트 가능성은 보너스입니다.