Как передать данные другому поставщику данных компонентов пользовательского интерфейса


У меня есть компонент пользовательского интерфейса сетки, который находится внутри набора полей некоторой отредактированной формы. Мне нужно передать entity_id из формы редактирования в сетку, где я могу отфильтровать коллекцию некоторых элементов по некоторому значению, и сетка покажет соответствующий результат. Я создал компонент сетки с помощью компонента insertListing.

<insertListing name="slide_grid">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="autoRender" xsi:type="boolean">true</item>
                <item name="source" xsi:type="string">slide</item>
                <item name="loading" xsi:type="boolean">true</item>
                <item name="dataScope" xsi:type="string">some_slider_slide_listing</item>
                <item name="externalProvider" xsi:type="string">${ $.ns }.some_slider_slide_listing_data_source</item>
                <item name="ns" xsi:type="string">some_slider_slide_listing</item>
                <item name="externalData" xsi:type="string">id</item>
                <item name="imports" xsi:type="array">
                    <item name="slider_id" xsi:type="string">${ $.provider }:data.entity_id</item>
                </item>
                <item name="exports" xsi:type="array">
                    <item name="slider_id" xsi:type="string">${ $.externalProvider }:params.slider_id</item>
                </item>
            </item>
        </argument>
    </insertListing>

Для передачи данных во внешний поставщик данных я использую

<item name="exports" xsi:type="array">
                <item name="slider_id" xsi:type="string">${ $.externalProvider }:params.slider_id</item>
            </item>

Внутри моего внешнего поставщика данных я пытаюсь передать данные через запрос.

$this->request->getParam('slider_id');

Но ничего. На интерфейсе я обнаружил, что Magento отправляет ajax-запрос с моим параметром, но я не могу поймать это в своем поставщике данных и отфильтровать коллекцию.

Author: Mistery, 2017-08-19

3 answers

Для добавления списка вставки по параметру родительского компонента пользовательского интерфейса мы можем использовать приведенный ниже код.

Здесь externalProvider тег предназначен для добавления поставщика источника списка, который мы вставляем.

Здесь imports тег используется для импорта параметров текущего источника данных формы

Здесь exports тег используется для экспорта текущих параметров данных формы в список, который будет вставлен.

<insertListing name="slide_grid">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="autoRender" xsi:type="boolean">true</item>
            <item name="ns" xsi:type="string">slide_grid</item><-- data source of the inserted listing -->
            <item name="externalProvider" xsi:type="string">colors_one_listing.colors_one_listing_data_source</item><!-- your insert listing data provider source -->
            <item name="imports" xsi:type="array">
                <item name="spd_id" xsi:type="string">${ $.provider }:data.slider_id</item>
            </item>
            <item name="exports" xsi:type="array">
                <item name="slider_id" xsi:type="string">${ $.externalProvider }:params.slider_id</item>
            </item>
        </item>
    </argument>
</insertListing>

Добавьте соединение с соответствующим столбцом в текущую коллекцию для создания его используют двумя способами:

  1. Фильтр по сетке Источник данных > имя аргумента > "Поставщик данных"> имя аргумента > "данные"> имя элемента "конфигурация"> имя элемента="filter_url_params"=> имя элемента> "идентификатор слайдера".

Для получения более подробной информации проверьте код ниже:

<dataSource name="..._listing_data_source">
    <argument name="dataProvider" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">...\...\Ui\DataProvider\...\Grid\...DataProvider</argument>
        <argument name="name" xsi:type="string">..._listing_data_source</argument>
        <argument name="primaryFieldName" xsi:type="string">id</argument>
        <argument name="requestFieldName" xsi:type="string">slider_id</argument>
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
                <item name="update_url" xsi:type="url" path="mui/index/render"/>
                <item name="filter_url_params" xsi:type="array">
                    <item name="slider_id" xsi:type="string">*</item>
                </item>
                <item name="storageConfig" xsi:type="array">
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </item>
        </argument>
    </argument>
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
        </item>
    </argument>
</dataSource>
  1. Отфильтруйте поставщика данных для вставленного списка.

В поставщике данных добавьте фильтр для этого параметра:

$collection->addFieldToFilter('slider_id', $this->request->getParam('slider_id'));

Мне нравится следовать варианту 1.

 4
Author: Ashish Raj, 2019-01-28 06:39:57

После прочтения и отладки файлов ядра Magento 2 Я нашел чистое и простое решение по этой проблеме. Передача данных из пользовательской формы в пользовательскую сетку с использованием UIComponent Insertlisting действительно сложна и вообще не документирована.

enter image description here

Объект InsertListing имеет два параметра под тегом: экспорт и импорт, которые я использовал в своем списке:

<fieldset name="relatedto" >
    <settings>
        <label>Related to</label>
        <componentType>fieldset</componentType>
    </settings>

    <insertListing name="threadrelated_listing">
        <settings>
            <dataLinks>
                <exports>false</exports>
                <imports>true</imports>
            </dataLinks>
            <externalProvider>mycompany_helpdesk_threadrelated_listing.mycompany_helpdesk_threadrelated_listing_data_source</externalProvider>
            <selectionsProvider>mycompany_helpdesk_threadrelated_listing.mycompany_helpdesk_threadrelated_listing.mycompany_helpdesk_threadrelated_columns.ids</selectionsProvider>
            <autoRender>true</autoRender>
            <dataScope>mycompany_helpdesk_threadrelated_listing</dataScope>
            <ns>mycompany_helpdesk_threadrelated_listing</ns>
            <exports>
                <link name="ticket_id">${ $.externalProvider }:params.ticket_id</link>
            </exports>
            <imports>
                <link name="ticket_id">${ $.provider }:data.ticket_id</link>
            </imports>
        </settings>
    </insertListing>
</fieldset>

И после нескольких часов, чтобы понять и найти решение по в сети я не нашел ни одной зацепки!

Итак, я прочитал файл ядра Magento и обнаружил, что Magento позволяет создавать сетки вложенных списков в проекте. Иногда он использует старый метод вставки блоков и несколько раз новый метод перечисления компонентов UIComponent.

Я нашел сетку списка адресов клиентов в customer_address_listing.xml (/vendor/magento/module-customer/view/adminhtml/ui_component/customer_address_listing.xml ) и он получает идентификатор parent_id переменная, определенная в customer_form.xml (/vendor/magento/module-customer/view/base/ui_component/customer_form.xml ) но вопрос в следующем:

Как Magento передает данные из формы во вложенную таблицу списков?

Magento передает данные с помощью параметра QUERYSTRING!

Если вы прочтете DataProvider.php файл, вы будете удивлены, потому что он получает переменную parent_id (customer) по СТРОКЕ ЗАПРОСА! Смотреть на /vendor/magento/module-customer/Ui/Component/Listing/Address/DataProvider.php строка 58:

/**
 * Add country key for default billing/shipping blocks on customer addresses tab
 *
 * @return array
 */
public function getData(): array
{
    $collection = $this->getCollection();
    $data['items'] = [];
    if ($this->request->getParam('parent_id')) {
        $collection->addFieldToFilter('parent_id', $this->request->getParam('parent_id'));
        $data = $collection->toArray();
    }
    foreach ($data['items'] as $key => $item) {
        if (isset($item['country_id']) && !isset($item['country'])) {
            $data['items'][$key]['country'] = $this->countryDirectory->loadByCode($item['country_id'])->getName();
        }
    }

    return $data;
}

Но как мне задать параметр в URL-адресе listinggrid? Я нашел параметр filterUrlParams, но здесь также есть странная проблема! Давайте взглянем на этот фрагмент кода источника данных:

<dataSource name="mycompany_helpdesk_threadrelated_listing_data_source" component="Magento_Ui/js/grid/provider">
    <settings>
        <filterUrlParams>
            <param name="ticket_id">*</param>
        </filterUrlParams>
        <storageConfig>
            <param name="indexField" xsi:type="string">threadrelated_id</param>
        </storageConfig>
        <updateUrl path="mui/index/render"/>
    </settings>
    <dataProvider class="mycompany\Helpdesk\Ui\DataProvider\Threadrelated\ThreadRelatedDataProvider" name="mycompany_helpdesk_threadrelated_listing_data_source">
        <settings>
            <requestFieldName>id</requestFieldName>
            <primaryFieldName>threadrelated_id</primaryFieldName>
        </settings>
    </dataProvider>
</dataSource>

Я установил идентификатор ticket_id с подстановочным знаком (*), что означает: получите все билеты! но если вы не зададите какой-либо идентификатор в параметрах FILTERURL, URL-адрес для вставки списка НЕ имеет НИКАКОГО НАБОРА ticket_id! Так что почему?!

Решение, предложенное @hashish-raj, не работает для меня.

Вот все сообщения, которые я прочитал об этой проблеме:

В конце я нашел временный обходной путь с использованием основного сеанса и сохраняю параметр ticket_id в сеансе. Затем в пользовательском поставщике данных я проверил его и применил к коллекции:

/***
 * @return array
 */
public function getData()
{

    $collection = $this->getSearchResult();

    /** see: check Mycompany\Helpdesk\Controller\Adminhtml\Ticket\Edit **/
    if($this->coreSession->getTicketId()){
        $collection->addFieldToFilter('ticket_id', ['eq' => $this->coreSession->getTicketId()]);
    }

    return $this->searchResultToOutput($collection);

}

Если у вас есть обходной путь или вы поняли, как Magento обрабатывает эти отношения между UIComponent, пожалуйста, поделитесь своими знаниями!

Я открыл "награду" здесь: https://magento.stackexchange.com/a/306537/2004

 4
Author: Michelangelo, 2020-03-09 10:37:33

Это работает для меня!

// Vendor/Module/view/adminhtml/ui_component/customer_form.xml
...
<insertListing name="..._listing">
        <settings>
            <externalProvider>..._listing...._listing_data_source</externalProvider>
            <selectionsProvider>..._listing...._listing...._listing_columns.ids</selectionsProvider>
            <autoRender>true</autoRender>
            <dataScope>company_account_listing</dataScope>
            <ns>company_account_listing</ns>
            <imports>
                <link name="same">${ $.provider }:data.customer.website_id</link>
            </imports>
            <exports>
                <link name="same">${ $.externalProvider }:params.new_new</link>
            </exports>
        </settings>
    </insertListing>

// Vendor/Module/view/adminhtml/ui_component/...listing.xml
<dataSource name="..._listing_data_source" component="Magento_Ui/js/grid/provider">
    <settings>
        <storageConfig>
            <param name="indexField" xsi:type="string">entity_id</param>
        </storageConfig>
        <updateUrl path="mui/index/render"/>
    </settings>
    <aclResource>anonymous</aclResource>
    <dataProvider class="Vendor\Module\Ui\Component\DataProvider" name="..._listing_data_source">
        <settings>
            <requestFieldName>entity_id</requestFieldName>
            <primaryFieldName>entity_id</primaryFieldName>
        </settings>
    </dataProvider>
</dataSource>
 0
Author: Vadu, 2021-01-13 18:13:11