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.