Como passar dados para outro componente da interface do usuário DataProvider


9

Eu tenho um componente de interface do usuário da grade que está dentro do fieldset de algum formulário editado. Eu preciso passar um entity_iddo formulário de edição para a grade, onde eu possa filtrar a coleção de alguns itens por algum valor, e a grade mostrará o resultado apropriado. Criei o componente da grade usando um componente 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>

Para transferir dados para o dataProvider externo, estou usando

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

Dentro do meu provedor de dados externo, estou tentando obter os dados através de solicitação.

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

Mas nada. No frontend, descobri que o Magento enviava uma solicitação ajax com meu parâmetro, mas não consigo capturar isso no meu DataProvider e filtrar a coleção.


A abordagem que obtive do código principal do Magento 2 (por exemplo, nos produtos CustomOptions form Modifier). Mas, por alguma razão, não está funcionando para mim.
— Mistery

Você conseguiu qualquer solução do problema ... Eu estou enfrentando mesmo problema, por favor, ajuda se você tiver resolvido ...
— Ashish Raj

Eu fiz uma mesma tag insertListing como você, mas a solicitação ajax não tinha o meu parâmetro na tag exportações .... Você encontrou a solução?
— thanhdv2811

Respostas:


2

Para adicionar a listagem de inserção por param do componente ui-pai, podemos usar o código abaixo.

A externalProvidertag Here é para adicionar o provedor de origem da listagem que estamos inserindo.

A importstag Here é usada para importar parâmetros da fonte de dados do formulário atual

A exportstag Here é usada para exportar os parâmetros de dados do formulário atual para a listagem que será inserida.

<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>

Adicione junção com a coluna relevante à coleção atual para usá-la de duas maneiras:

  1. Filtre por grade dataSource> nome do argumento> "dataProvider"> nome do argumento> "data"> nome do item "config"> nome do item = "filter_url_params" => nome do item> "slider_id" .

Para mais detalhes, verifique o código abaixo:

<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. Filtre o provedor de dados da listagem inserida.

No provedor de dados, adicione filtro para este parâmetro:

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

Eu gosto de seguir a opção 1.


dataProvider não possui os parâmetros filter_url_params na definição. Atualize sua resposta.
— Michelangelo

1

Depois de ler e depurar os arquivos principais do Magento 2 , encontrei uma solução limpa e simples sobre esse problema. A transmissão de dados de um formulário personalizado para uma grade personalizada usando o UIComponent insertListing é realmente difícil e não está documentada.

insira a descrição da imagem aqui

O objeto InsertListing possui dois parâmetros na tag: exportações e importações que usei na minha listagem:

<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>

e depois de horas para entender e encontrar uma solução na web, não encontrei nenhuma pista!

Então, eu li o arquivo Magento Core e descobri que o Magento combina a maneira de criar as grades de listagem aninhadas no projeto. Às vezes, ele usa o antigo método de inserção de bloco e algumas vezes o novo método de listagem UIComponent.

Encontrei a grade de listagem de endereços do cliente em customer_address_listing.xml (/vendor/magento/module-customer/view/adminhtml/ui_component/customer_address_listing.xml) e obtém a variável parent_id definida em customer_form.xml (/ vendor / magento /module-customer/view/base/ui_component/customer_form.xml), mas a pergunta é:

Como o Magento passa os dados do formulário para a grade de listagem aninhada?

Magento passa os dados pelo QUERYSTRING PARAMETER!

Se você ler o arquivo DataProvider.php, ficará surpreso porque ele obtém a variável parent_id (customer) pela QUERYSTRING! Veja /vendor/magento/module-customer/Ui/Component/Listing/Address/DataProvider.php linha 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;
}

mas como faço para definir o parâmetro no URL da lista de listagem? Eu encontrei o parâmetro filterUrlParams, mas há um problema estranho também aqui! Vamos dar uma olhada neste trecho de código dataSource:

<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>

Eu configurei o ticket_id com um curinga (*) que significa: obtenha todos os tickets! mas se você não definir nenhum ID no filterUrlParams, o URL insertListing NÃO TEM QUALQUER ticket_id SET! Então por que?!

A solução oferecida pelo @ hashish-raj não funciona para mim.

Estes são todos os posts que li sobre esse problema:

No final, encontrei uma solução temporária usando a sessão principal e armazene o parâmetro ticket_id na sessão. Em seguida, no provedor de dados personalizado, verifiquei e apliquei na coleção:

/***
 * @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);

}

Se você tem uma solução alternativa ou entende como o Magento lida com esse relacionamento entre o UIComponent , compartilhe seu conhecimento!

Abri uma "recompensa" aqui: https://magento.stackexchange.com/a/306537/2004

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.