Cómo pasar datos a otro componente de interfaz de usuario DataProvider

9

Tengo un componente de interfaz de usuario de cuadrícula que está dentro del conjunto de campos de alguna forma editada. Necesito pasar un entity_idformulario de edición a la cuadrícula donde puedo filtrar la colección de algunos elementos por algún valor, y la cuadrícula mostrará el resultado apropiado. Creé el componente de cuadrícula usando un 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 datos a un proveedor externo de datos que estoy usando

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

Dentro de mi proveedor de datos externo, estoy tratando de obtener los datos a través de una solicitud.

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

Pero nada. En la interfaz, encontré que Magento enviaba una solicitud ajax con mi parámetro, pero no puedo captar esto en mi DataProvider y filtrar la colección.

Misterio
fuente
El enfoque que obtuve del código principal de Magento 2 (por ejemplo, en los productos CustomOptions form Modifier). Pero por alguna razón no me funciona.
Mistery
¿Obtuviste alguna solución al problema? Estoy enfrentando el mismo problema, por favor, ayuda si has resuelto ...
Ashish Raj
Hice una misma etiqueta insertListing como usted, pero la solicitud ajax no tenía mi parámetro en la etiqueta de exportaciones ... ¿Encontró la solución?
thanhdv2811

Respuestas:

2

Para agregar un listado de inserción por parámetro del componente ui principal, podemos usar el siguiente código.

Aquí la externalProvideretiqueta es para agregar el proveedor de origen de la lista que estamos insertando.

Aquí la importsetiqueta se usa para importar parámetros del origen de datos del formulario actual

Aquí, la exportsetiqueta se utiliza para exportar los parámetros de datos del formulario actual a la lista que se va a insertar.

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

Agregue unir con la columna relevante a la colección actual para que se use de dos maneras:

  1. Filtre por fuente de datos de cuadrícula > nombre del argumento> "proveedor de datos"> nombre del argumento> "datos"> nombre del elemento "config"> nombre del elemento = "filter_url_params" => nombre del elemento> "slider_id" .

Para obtener más detalles, consulte el siguiente código:

<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 el proveedor de datos de la lista insertada.

En el proveedor de datos, agregue el filtro para este parámetro:

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

Me gusta seguir la opción 1.

Ashish Raj
fuente
dataProvider no tiene los parámetros filter_url_params en la definición. Por favor actualice su respuesta.
Miguel Ángel
1

Después de leer y depurar los archivos principales de Magento 2, he encontrado una solución limpia y simple sobre este problema. Pasar datos de un formulario personalizado a una cuadrícula personalizada usando UIComponent insertListing es realmente difícil y no está documentado en absoluto.

ingrese la descripción de la imagen aquí

El objeto InsertListing tiene dos parámetros debajo de la etiqueta: exportaciones e importaciones que he usado en mi listado:

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

y después de horas de entender y encontrar una solución en la web, ¡no he encontrado ninguna pista!

Entonces, leí el archivo Magento Core y descubrí que Magento combina la forma de crear las cuadrículas de listado anidadas en el proyecto. En algún momento utiliza el antiguo método de inserción de bloque y pocas veces el nuevo método de listado UIComponent.

He encontrado la cuadrícula de listado de direcciones de clientes en customer_address_listing.xml (/vendor/magento/module-customer/view/adminhtml/ui_component/customer_address_listing.xml) y obtiene la variable parent_id definida en customer_form.xml (/ vendor / magento /module-customer/view/base/ui_component/customer_form.xml) pero la pregunta es:

¿Cómo pasa Magento los datos del formulario a la cuadrícula de listado anidado?

¡Magento pasa los datos por el PARÁMETRO QUERYSTRING!

Si lee el archivo DataProvider.php, se sorprenderá porque ¡QUERYSTRING obtiene la variable parent_id (customer)! Mire /vendor/magento/module-customer/Ui/Component/Listing/Address/DataProvider.php línea 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;
}

pero ¿cómo configuro el parámetro en la URL de grid de listado? ¡He encontrado el parámetro filterUrlParams pero también hay un problema extraño aquí! Echemos un vistazo a este código recortado de 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>

He configurado ticket_id con un comodín (*) que significa: ¡obtenga todos los tickets! pero si no configura ningún ID en filterUrlParams, la URL insertListing NO TIENE NINGÚN ticket_id SET! ¡¿Entonces por qué?!

La solución ofrecida por @ hashish-raj no funciona para mí.

Estas son todas las publicaciones que he leído sobre este tema:

Al final, encontré una solución temporal usando la sesión principal y almaceno el parámetro ticket_id en la sesión. Luego, en el proveedor de datos personalizado, lo he verificado y lo he aplicado a la colección:

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

}

Si tiene una solución alternativa o ha entendido cómo Magento maneja esta relación entre el componente UIC , ¡comparta su conocimiento!

He abierto una "recompensa" aquí: https://magento.stackexchange.com/a/306537/2004

Miguel Ángel
fuente