DynamicRows (หรือ Associative Array) ใน Magento 2 REST API
ฉันใช้ Magento 2 REST API สำหรับแอปพลิเคชันมือถือ ฉันกำลังเผชิญกับความซับซ้อนดังนั้นฉันจึงต้องการความช่วยเหลือจากคุณ
ฉันมี DynamicRows องค์ประกอบที่มีสองเขตข้อมูลในแบบฟอร์ม UI ชื่อของสนามคือการแปล
<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% ความสามารถในการทดสอบเป็นโบนัส