Magento 2 REST API의 DynamicRows (또는 연관 배열)
모바일 애플리케이션에 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 가 다른 필드가 두 개 이상있을 수 있다는 점을 염두에두고 예상 결과를 얻으려면 어떻게해야 합니까?
답변
나는 다음 사항에 도달했습니다.
나는 당신이 그것으로부터 더 많은 것을 얻기 위해 고군분투 할 것이라고 생각합니다. 기본적으로 항목 키는 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;
}
}
원하는 결과를 얻으려면 더 많은 클래스를 만들어야합니다.
이 경우 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 두 가지 방법이 있어야합니다.
getLabelgetValue
이것은 장황 해 보일 수 있습니다. 그러나이 경로를 통해 출력을 100 % 제어 할 수 있습니다. 테스트 가능성은 보너스입니다.