So übergeben Sie Daten an einen anderen DataProvider mit UI-Komponenten

9

Ich habe eine Raster-UI-Komponente, die sich innerhalb des Feldsatzes eines bearbeiteten Formulars befindet. Ich muss ein entity_idFormular aus dem Bearbeitungsformular an das Raster übergeben, in dem ich die Sammlung einiger Elemente nach einem bestimmten Wert filtern kann, und das Raster zeigt das entsprechende Ergebnis an. Ich habe die Rasterkomponente mit einer insertListing-Komponente erstellt.

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

Für die Übertragung von Daten an einen externen dataProvider verwende ich

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

In meinem externen Datenprovider versuche ich, die Daten auf Anfrage zu erhalten.

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

Aber nichts. Im Frontend habe ich festgestellt, dass Magento eine Ajax-Anfrage mit meinem Parameter sendet, aber ich kann dies in meinem DataProvider nicht abfangen und die Sammlung filtern.

Geheimnis
quelle
Der Ansatz, den ich vom Magento 2-Kerncode erhalten habe (zum Beispiel in Produkten CustomOptions form Modifier). Aber aus irgendeinem Grund funktioniert es bei mir nicht.
Mistery
Haben Sie eine Lösung des Problems bekommen ... Ich stehe vor dem gleichen Problem, bitte helfen Sie, wenn Sie gelöst haben ...
Ashish Raj
Ich habe das gleiche insertListing-Tag wie Sie erstellt, aber die Ajax-Anforderung hatte meinen Parameter nicht im Export-Tag. Haben Sie die Lösung gefunden?
thanhdv2811

Antworten:

1

Für das Hinzufügen einer Insert-Liste nach Parameter der übergeordneten UI-Komponente können wir den folgenden Code verwenden.

Das externalProviderTag dient zum Hinzufügen eines Quellanbieters der Liste, die wir einfügen.

Hier wird das importsTag für den Importparameter der aktuellen Formulardatenquelle verwendet

Hier wird das exportsTag zum Exportieren der aktuellen Formulardatenparameter in die Liste verwendet, die eingefügt werden soll.

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

Fügen Sie der aktuellen Sammlung einen Join mit der entsprechenden Spalte hinzu, damit er auf zwei Arten verwendet werden kann:

  1. Filtern nach Raster dataSource> Argumentname> "dataProvider"> Argumentname> "Daten"> Elementname "config"> Elementname = "filter_url_params" => Elementname> "slider_id" .

Weitere Informationen finden Sie im folgenden Code:

<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. Filtern Sie den Datenprovider der eingefügten Liste.

Fügen Sie im Datenprovider Filter für diesen Parameter hinzu:

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

Ich folge gerne Option 1.

Ashish Raj
quelle
dataProvider enthält die Parameter filter_url_params nicht in der Definition. Bitte aktualisieren Sie Ihre Antwort.
Michelangelo
1

Nach dem Lesen und Debuggen der Magento 2-Kerndateien habe ich eine saubere und einfache Lösung für dieses Problem gefunden. Das Übergeben von Daten aus einem benutzerdefinierten Formular an ein benutzerdefiniertes Raster mithilfe der UIComponent insertListing ist sehr schwierig und überhaupt nicht dokumentiert.

Geben Sie hier die Bildbeschreibung ein

Das InsertListing-Objekt verfügt über zwei Parameter unter dem Tag: Exporte und Importe, die ich in meiner Liste verwendet habe:

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

und nach Stunden, um eine Lösung im Web zu verstehen und zu finden, habe ich keinen Hinweis gefunden!

Ich habe also die Magento Core-Datei gelesen und festgestellt, dass Magento die Methode zum Erstellen der verschachtelten Auflistungsraster im Projekt miteinander verbindet. Manchmal wird die alte Blockeinfügemethode und einige Male die neue UIComponent-Listungsmethode verwendet.

Ich habe das Raster für die Auflistung der Kundenadressen in der Datei customer_address_listing.xml (/vendor/magento/module-customer/view/adminhtml/ui_component/customer_address_listing.xml) gefunden und es wird die in der customer_form.xml (/ vendor / magento definierte Variable parent_id) abgerufen /module-customer/view/base/ui_component/customer_form.xml) aber die Frage ist:

Wie übergibt Magento die Daten aus dem Formular an das verschachtelte Listenraster?

Magento übergibt die Daten an den QUERYSTRING PARAMETER!

Wenn Sie die Datei DataProvider.php lesen, werden Sie überrascht sein, da sie die Variable parent_id (customer) vom QUERYSTRING erhält! Schauen Sie sich die Zeile 58 unter /vendor/magento/module-customer/Ui/Component/Listing/Address/DataProvider.php an:

/**
 * 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;
}

aber wie setze ich den Parameter in der Listinggrid-URL? Ich habe den Parameter filterUrlParams gefunden, aber auch hier gibt es ein merkwürdiges Problem! Schauen wir uns diesen Ausschnitt aus dem dataSource-Code an:

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

Ich habe die ticket_id mit einem Platzhalter (*) gesetzt, der bedeutet: alle Tickets erhalten! Wenn Sie jedoch keine ID in den filterUrlParams festlegen, hat die insertListing-URL KEINE ticket_id SET! Warum also?!

Die von @ hashish-raj angebotene Lösung funktioniert bei mir nicht.

Dies sind alle Beiträge, die ich zu diesem Thema gelesen habe:

Am Ende habe ich eine temporäre Problemumgehung mithilfe der Kernsitzung gefunden und den Parameter ticket_id in der Sitzung gespeichert. Dann habe ich es im benutzerdefinierten Datenprovider überprüft und auf die Sammlung angewendet:

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

}

Wenn Sie eine Problemumgehung haben oder verstanden haben, wie Magento mit dieser Beziehung zwischen der UIComponent umgeht , teilen Sie bitte Ihr Wissen mit!

Ich habe hier ein "Kopfgeld" eröffnet: https://magento.stackexchange.com/a/306537/2004

Michelangelo
quelle