Comment passer des données à un autre composant d'interface utilisateur DataProvider

9

J'ai un composant d'interface utilisateur de grille qui se trouve à l'intérieur de fieldset d'une forme modifiée. J'ai besoin de passer d'un entity_idformulaire d'édition à une grille où je peux filtrer la collection de certains éléments par une certaine valeur, et la grille affichera le résultat approprié. J'ai créé le composant de grille à l'aide d'un composant 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>

Pour transférer des données vers des données externes Fournisseur que j'utilise

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

Dans mon fournisseur de données externe, j'essaie d'obtenir les données par le biais d'une demande.

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

Mais rien. Sur le frontend, j'ai trouvé que Magento envoyait une requête ajax avec mon paramètre mais je ne peux pas attraper cela dans mon DataProvider et filtrer la collection.

Mystère
la source
L'approche que j'ai obtenue du code de base de Magento 2 (par exemple dans les produits CustomOptions form Modifier). Mais pour une raison quelconque, cela ne fonctionne pas pour moi.
Mistery
Avez-vous trouvé une solution au problème ... Je fais face au même problème, aidez-nous si vous avez résolu ...
Ashish Raj
J'ai fait une même balise insertListing comme vous mais la requête ajax n'avait pas mon paramètre dans la balise exports .... Avez-vous trouvé la solution?
thanhdv2811

Réponses:

2

Pour ajouter une liste d'insertions par paramètre du composant ui parent, nous pouvons utiliser le code ci-dessous.

Ici, la externalProviderbalise est pour ajouter le fournisseur source de la liste que nous insérons.

Ici, la importsbalise est utilisée pour importer les paramètres de la source de données du formulaire actuel

Ici, la exportsbalise est utilisée pour exporter les paramètres de données de formulaire actuels vers la liste qui va être insérée.

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

Ajoutez la jointure avec la colonne appropriée à la collection actuelle pour l'utiliser de deux manières:

  1. Filtrer par grille dataSource> nom d'argument> "dataProvider"> nom d'argument> "data"> nom d'élément "config"> nom d'élément = "filter_url_params" => nom d'élément> "slider_id" .

Pour plus de détails, vérifiez le code ci-dessous:

<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. Filtrez le fournisseur de données de la liste insérée.

Dans le fournisseur de données, ajoutez un filtre pour ce paramètre:

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

J'aime suivre l'option 1.

Ashish Raj
la source
dataProvider n'a pas les paramètres filter_url_params dans la définition. Veuillez mettre à jour votre réponse.
Michelangelo
1

Après avoir lu et débogué les fichiers principaux de Magento 2, j'ai trouvé une solution propre et simple à ce problème. Passer des données d'un formulaire personnalisé à une grille personnalisée à l'aide de la liste d'insertion UIComponent est vraiment difficile et n'est pas du tout documenté.

entrez la description de l'image ici

L'objet InsertListing a deux paramètres sous la balise: les exportations et les importations que j'ai utilisées dans ma liste:

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

et après des heures pour comprendre et trouver une solution sur le web, je n'ai trouvé aucun indice!

J'ai donc lu le fichier Magento Core et j'ai découvert que Magento maillait la façon de créer les grilles de listes imbriquées dans le projet. Parfois, il utilise l'ancienne méthode d'insertion de blocs et quelques fois la nouvelle méthode de listage UIComponent.

J'ai trouvé la grille de liste d'adresses client dans customer_address_listing.xml (/vendor/magento/module-customer/view/adminhtml/ui_component/customer_address_listing.xml) et obtient la variable parent_id définie dans customer_form.xml (/ vendor / magento /module-customer/view/base/ui_component/customer_form.xml) mais la question est:

Comment Magento transmet les données du formulaire à la grille de liste imbriquée?

Magento transmet les données par le PARAMÈTRE QUERYSTRING!

Si vous lisez le fichier DataProvider.php, vous serez surpris car il obtient la variable parent_id (client) par QUERYSTRING! Regardez /vendor/magento/module-customer/Ui/Component/Listing/Address/DataProvider.php ligne 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;
}

mais comment définir le paramètre dans l'URL de la liste de diffusion? J'ai trouvé le paramètre filterUrlParams mais il y a aussi un problème étrange ici! Jetons un coup d'œil à ce code de dataSource coupé:

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

J'ai mis le ticket_id avec un caractère générique (*) que cela signifie: obtenez tous les billets! mais si vous ne définissez aucun ID dans filterUrlParams, l'URL insertListing N'A AUCUN SET ticket_id SET! Alors pourquoi?!

La solution proposée par @ hashish-raj ne fonctionne pas pour moi.

Ce sont tous les articles que j'ai lus sur ce problème:

À la fin, j'ai trouvé une solution de contournement temporaire en utilisant la session principale et stocke le paramètre ticket_id dans la session. Ensuite, dans le fournisseur de données personnalisé, je l'ai vérifié et je l'ai appliqué à la collection:

/***
 * @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 vous avez une solution de contournement ou si vous avez compris comment Magento gère cette relation entre l'UIComponent , veuillez partager vos connaissances!

J'ai ouvert une "prime" ici: https://magento.stackexchange.com/a/306537/2004

Michel-Ange
la source