Objaśnienie siatki składników interfejsu użytkownika w Magento 2


91

Czy istnieje dobre wyjaśnienie i / lub próbka konfiguracji minimalnej niezbędnej do utworzenia siatki składników interfejsu użytkownika w Magento 2?

Wiem, że istnieją niezliczone podstawowe elementy, takie jak

./vendor/magento/module-catalog/view/adminhtml/ui_component/product_listing.xml

Jednak te pliki XML są ekspansywne i nie ma żadnego wyjaśnienia na temat tego, co robi każdy węzeł, ani tego, jak użyć go do zbudowania siatki od zera.

Jest też ten przykładowy moduł , ale to

  1. Wygląda na formę
  2. Brakuje kontekstu / wyjaśnienia na temat tego, co robi każdy węzeł

Szukam informacji „na początek”, które pozwoliłyby mi zbudować siatkę dla mojej własnej kolekcji modeli CRUD.


6
Nie do końca warta pełnej odpowiedzi - ale moja seria komponentów interfejsu użytkownika jest dobrym miejscem do rozpoczęcia: alanstorm.com/category/magento-2/#magento-2-ui
Alan Storm

Odpowiedzi:


166

[EDYCJA 3 października 2018 r.]

Aktualizacja linków do devdocs: 2.0 - https://devdocs.magento.com/guides/v2.0/ui-components/ui-listing-grid.html i https://devdocs.magento.com/guides/v2. 0 / ui-components / ui-wtórny.html

2.1 - https://devdocs.magento.com/guides/v2.1/ui_comp_guide/components/ui-listing-grid.html

2.2 - https://devdocs.magento.com/guides/v2.2/ui_comp_guide/components/ui-listing-grid.html

[EDIT 21 stycznia 2016 r.]

Od 20.01.2016 magento2 devdocs zostało zaktualizowane o rozszerzoną dokumentację komponentów interfejsu użytkownika. Nie sprawdziłem go dokładnie, ale mogą zawierać więcej informacji niż odpowiedź, którą udzieliłem kilka dni temu, więc w interesie twojego czasu możesz zobaczyć http://devdocs.magento.com/guides/v2.0/ui -library / ui-library-wtórna.html

[/EDYTOWAĆ]

Pracuję z Magento2 od ponad miesiąca i właśnie to zauważyłem w nowym sposobie tworzenia siatek.

Składnik interfejsu Magento 2 UI

1) plik układu wewnątrz Company/Module/view/adminhtml/layout/module_controller_action.xmldefiniuje siatkę jako komponent uiComponent z:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <body>
        <referenceContainer name="content">
            <uiComponent name="listing_name"/>
        </referenceContainer>
    </body>
</page>

2) uiComponent jest zdefiniowany w Company/Module/view/adminhtml/ui_component/listing_name.xmlpliku. Nazwa pliku musi być taka sama jak nazwa uiComponent używana w pliku układu. Struktura pliku może na pierwszy rzut oka wydawać się skomplikowana, ale jak zwykle są to niektóre powtarzające się węzły. Aby było to proste, pokrójmy go. Głównym węzłem pliku komponentu jest <listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">. Jest naprawiony i uważam, że wymaga atrybutu lokalizacji przestrzeni nazw. Następne są zazwyczaj 4 węzły wewnątrz <listing />węzła: <argument />, <dataSource />, <container />i <columns />. Nie jest to jednak ścisła konfiguracja, ponieważ <argument />węzeł może zostać zduplikowany w celu zapewnienia większej konfiguracji lub <container />jak na liście stron cms, która z jakiegoś powodu dodaje „lepki” pojemnik.

Pierwszy węzeł to <argument />. Ten węzeł definiuje dane dla komponentu. Zwykle musisz podać coś takiego:

<argument name="data" xsi:type="array">
    <item name="js_config" xsi:type="array">
        <item name="provider" xsi:type="string">listing_name.listing_name_data_source</item>
        <item name="deps" xsi:type="string">listing_name.listing_name_data_source</item>
    </item>
    <item name="spinner" xsi:type="string">listing_columns</item>
    <item name="buttons" xsi:type="array">
        <item name="add" xsi:type="array">
            <item name="name" xsi:type="string">add</item>
            <item name="label" xsi:type="string" translate="true">Add New Item</item>
            <item name="class" xsi:type="string">primary</item>
            <item name="url" xsi:type="string">*/*/new</item>
        </item>
    </item>
</argument>

<argument />węzeł wymaga atrybutu name. W tym przypadku dataokreśla podstawowe informacje o komponencie. Zawiera wiele <item />węzłów dla każdej określonej części konfiguracji. js_configinformuje komponent, gdzie są dostawcy danych i zależności w konfiguracji listingu xml (co myślę, że jest konwertowane na hash javascript). providerwartość składa się z nazwy listy używanej w pliku układu i unikalnej nazwy źródła danych, która będzie później używana. Na tych listach zameldowałem się w Magento provideri depssą takie same. Nie jestem pewien, jaki pożytek z posiadania tego innego. spinnerprzyjmuje nazwę węzła, w którym zdefiniowano kolumny siatki. buttonspozwala dodawać przyciski na górze siatki. W większości przypadków byłby to tylko Add newprzycisk. Przyciski mają kilka elementów:nameużywany jako identyfikator elementu, labelto, co mówi przycisk, classjest klasą przycisku i urljest linkiem, na który wskazuje. Gwiazdki zastępuje się częścią bieżącego adresu URL. Inne możliwe <item />węzły dla przycisku to: id, title, type(reset, złożyć lub przycisk), onclick(zamiast url, to ma pierwszeństwo), style, value, disabled. Element przycisku jest renderowany według Magento\Ui\Component\Control\Buttonklasy.

Następnie mamy <dataSource />węzeł:

<dataSource name="listing_name_data_source">
    <argument name="dataProvider" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">UniqueNameGridDataProvider</argument>
        <argument name="name" xsi:type="string">listing_name_data_source</argument>
        <argument name="primaryFieldName" xsi:type="string">database_id</argument>
        <argument name="requestFieldName" xsi:type="string">request_id</argument>
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="update_url" xsi:type="url" path="mui/index/render"/>
            </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>

nameużyte w <dataSource />węźle musi być zgodne z tym używanym w argument/js_config/provideri argument/js_config/deps. Następny węzeł określa, która klasa jest odpowiedzialna za przygotowanie danych do siatki. classargument wymaga unikalnej nazwy, która zostanie dopasowana di.xml. primaryFieldNameodnosi się do podstawowej kolumny bazy danych i requestFieldNamezmiennej w żądaniach HTTP. Mogą być równe, ale nie muszą, lista stron CMS używa page_idjako primaryFieldNamei idjako requestFieldName. update_urlodnosi się do punktu wejścia, do którego wysyłane są wywołania ajax w celu filtrowania i sortowania. Drugi argument <dataSource />dotyczy pliku javascript, który obsługuje część js wysyłania i przetwarzania wywołań ajax dla siatki. Domyślny plik to Magento/Ui/view/base/web/js/grid/provider.js.

Innym węzłem jest <container />.

<container name="listing_top"> ... </container>

Ponieważ zawiera wiele danych, podzielę je również. Jego dzieci są częściami całej strony. Pierwsze dziecko <argument />:

<argument name="data" xsi:type="array">
    <item name="config" xsi:type="array">
        <item name="template" xsi:type="string">ui/grid/toolbar</item>
    </item>
</argument>

Definiuje szablon nokaut odpowiedzialny za obsługę układu i wszystkich działań i domyślnie wskazuje na Magento/Ui/view/base/web/templates/grid/toolbar.html

Następny węzeł to (lub może być) <bookmark />

<bookmark name="bookmarks">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="storageConfig" xsi:type="array">
                <item name="namespace" xsi:type="string">listing_name</item>
            </item>
        </item>
    </argument>
</bookmark>

Ten węzeł dodaje do zakładek funkcję zakładek. Pozwala administratorowi skonfigurować różne „profile” siatki, która wyświetla różne kolumny. Dzięki temu możesz dodać wszystkie kolumny z tabeli do siatki i pozwolić użytkownikowi zdecydować, które informacje są dla niego istotne. namespacemusi pasować do nazwy użytej w pliku układu.

Innym węzłem jest <component />

<component name="columns_controls">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="columnsData" xsi:type="array">
                <item name="provider" xsi:type="string">listing_name.listing_name.listing_columns</item>
            </item>
            <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
            <item name="displayArea" xsi:type="string">dataGridActions</item>
        </item>
    </argument>
</component>

Mamy tutaj 3 wartości do skonfigurowania. Pierwszym z nich jest providernastępujący wzór [nazwa_listy_z gry]. [Nazwa_listy z gry]. [Nazwa_listy_węzła listy] (jak w przypadku listy węzłów / argumentu / pokrętła). componentodnosi się do pliku js, który wyświetla siatkę i domyślnie wskazuje punkty, do Magento/Ui/view/base/web/js/grid/controls/columns.jsktórych wykorzystuje szablon Magento/Ui/view/base/web/templates/grid/controls/columns.html. Ostatni element displayAreaokreśla, gdzie mają być wyświetlane kontrolki kolumn. Odnosi się do getRegion('dataGridActions')pliku zdefiniowanego w container/argument/config/template(domyślnie:) Magento/Ui/view/base/web/templates/grid/toolbar.html.

Następny węzeł to <filterSearch />

<filterSearch name="fulltext">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="provider" xsi:type="string">listing_name.listing_name_data_source</item>
            <item name="chipsProvider" xsi:type="string">listing_name.listing_name.listing_top.listing_filters_chips</item>
            <item name="storageConfig" xsi:type="array">
                <item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
                <item name="namespace" xsi:type="string">current.search</item>
            </item>
        </item>
    </argument>
</filterSearch>

Ten węzeł dodaje wyszukiwanie pełnotekstowe na stronie. Znajduje się nad siatką jako pojedyncze pole wprowadzania tekstu z „Szukaj według słowa kluczowego” jako symbolem zastępczym. Nie jestem pewien, jakie opcje są tutaj możliwe, ponieważ nie grałem zbyt wiele, ale listing_filters_chips odnosi się do Magento/Ui/view/base/web/js/grid/filters/chips.jspliku.

Następny węzeł to <filters />

<filters name="listing_filters">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="columnsProvider" xsi:type="string">listing_name.listing_name.listing_columns</item>
            <item name="storageConfig" xsi:type="array">
                <item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
                <item name="namespace" xsi:type="string">current.filters</item>
            </item>
            <item name="templates" xsi:type="array">
                <item name="filters" xsi:type="array">
                    <item name="select" xsi:type="array">
                        <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                        <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                    </item>
                </item>
            </item>
            <item name="childDefaults" xsi:type="array">
                <item name="provider" xsi:type="string">listing_name.listing_name.listing_top.listing_filters</item>
                <item name="imports" xsi:type="array">
                    <item name="visible" xsi:type="string">listing_name.listing_name.listing_columns.${ $.index }:visible</item>
                </item>
            </item>
        </item>
        <item name="observers" xsi:type="array">
            <item name="column" xsi:type="string">column</item>
        </item>
    </argument>
</filters>

Ten węzeł określa konfigurację filtrowania kolumn, która jest widoczna po kliknięciu przycisku „Filtry” w prawym górnym rogu nad siatką. columnsProviderma podobną strukturę jak poprzednie węzły, więc [nazwa_listy_z gry]. [nazwa_listy z gry]. [nazwa_kolekcji_listy]. storegeConfigwygląda jak [nazwa_wpisu_z gry]. [nazwa_wpisu z gry]. [nazwa_węzła kontenera] [nazwa_węzła zakładki]. W templateswęźle elementu możesz określić, które pliki są używane do renderowania określonych opcji filtrów. W tym przypadku zdefiniowano tylko opcję select, która używa Magento/Ui/view/base/web/js/form/element/ui-select.jsjako componenti Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.htmljako szablonu nokautu. Sprawdź, Magento/Ui/view/base/web/js/form/elementaby zobaczyć inne możliwości. W tym miejscu zdefiniowano tylko wybór, aby zastąpić wartości domyślne: Magento/Ui/view/base/web/js/form/element/select.jsi Magento/Ui/view/base/web/templates/grid/filters/elements/select.html. Domyślne wartości filtrów i innych węzłów są zdefiniowane w Magento/Ui/view/base/ui_component/etc/definition.xml.

Następny węzeł jest <massAction />i pozwala dodać masową akcję selekcji do siatki

<massaction name="listing_massaction">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="selectProvider" xsi:type="string">listing_name.listing_name.listing_columns.ids</item>
            <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
            <item name="indexField" xsi:type="string">database_id</item>
        </item>
    </argument>
    <action name="delete">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="type" xsi:type="string">delete</item>
                <item name="label" xsi:type="string" translate="true">Delete</item>
                <item name="url" xsi:type="url" path="*/*/massDelete"/>
                <item name="confirm" xsi:type="array">
                    <item name="title" xsi:type="string" translate="true">Delete items</item>
                    <item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected items?</item>
                </item>
            </item>
        </argument>
    </action>
    <action name="change_status">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="type" xsi:type="string">change_status</item>
                <item name="label" xsi:type="string" translate="true">Change Status</item>
            </item>
        </argument>
        <argument name="actions" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Company\Module\Ui\Component\MassAction\Status\Options</argument>
            <argument name="data" xsi:type="array">
                <item name="confirm" xsi:type="array">
                    <item name="title" xsi:type="string" translate="true">Change Status</item>
                    <item name="message" xsi:type="string" translate="true">Are you sure to change status for selected feed(s)?</item>
                </item>
            </argument>
        </argument>
    </action>
</massaction>

nameargument powinien być unikalny. Pierwszy węzeł potomny <argument />definiuje podstawowe dane. providerma taką samą strukturę jak inne węzły i odnosi się do kolumny nazwa węzła i jego kolumny id. W tej kolumnie znajdują się pola wyboru z wybranymi elementami do przetworzenia przez akcję masową. componentokreśla, który plik jest używany do renderowania i obsługi akcji masowej. Wartość domyślna to Magento_Ui/js/grid/massactions(wskazuje Magento/Ui/view/base/web/js/grid/massactions.js). Możesz użyć, Magento_Ui/js/grid/tree-massactionsaby dodać strukturę drzewiastą. W powyższym przypadku używam go do dodawania akcji „Zmień status”, która pokazuje opcje „włącz” i „wyłącz”. Po <argument />węźle możesz dodać tyle <action />węzłów, ile chcesz akcji. Każdy <action />węzeł ma podobny schemat. W pierwszym przypadku (akcja usuwania) węzeł wymaga unikalnej nazwy. Następnie argumentzawiera konfigurację gdzielabeljest widoczny w opcji select, urlpunkcie końcowym do wysłania danych i confirmdodaje modalne potwierdzenie przed wysłaniem. W przypadku „Zmień status” akcja urlw pierwszym argumentwęźle jest zalecana, ponieważ adresy URL są podawane według statusu według klasy zdefiniowanej w drugim argumentwęźle. Klasa powinna implementować interfejs Zend \ Stdlib \ JsonSerializable. Sprawdź Magento\Customer\Ui\Component\MassAction\Group\Optionsjako odniesienie.

Wreszcie w <container />węźle mamy <paging />węzeł, który definiuje paginację.

<paging name="listing_paging">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="storageConfig" xsi:type="array">
                <item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
                <item name="namespace" xsi:type="string">current.paging</item>
            </item>
            <item name="selectProvider" xsi:type="string">listing_name.listing_name.listing_columns.ids</item>
        </item>
    </argument>
</paging>

Struktura provideri selectProviderpowinna być teraz jasna.

Ostatni węzeł dla podstawowej siatki to <columns />. Zawiera całą definicję kolumn, które są dostępne do użytku przez administratora. Węzeł jest zdefiniowany jako

<columns name="listing_columns"> ... </columns>

a atrybut name jest używany w innych węzłach, gdy się do niego odwołuje. Pierwsze dziecko to

<argument name="data" xsi:type="array">
    <item name="config" xsi:type="array">
        <item name="storageConfig" xsi:type="array">
            <item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
            <item name="namespace" xsi:type="string">current</item>
        </item>
        <item name="childDefaults" xsi:type="array">
            <item name="storageConfig" xsi:type="array">
                <item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
                <item name="root" xsi:type="string">columns.${ $.index }</item>
                <item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
            </item>
            <item name="fieldAction" xsi:type="array">
                <item name="provider" xsi:type="string">name_listing.name_listing.listing_columns.actions</item>
                <item name="target" xsi:type="string">applyAction</item>
                <item name="params" xsi:type="array">
                    <item name="0" xsi:type="string">edit</item>
                    <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
                </item>
            </item>
        </item>
    </item>
</argument>

To, co tu zrobiłem, to podanie poprawnych providerwartości tylko zgodnie ze schematem zastosowanym na liście. fieldActionwęzeł pozwala zdefiniować akcję uruchamianą po kliknięciu komórki. Ustawienia domyślne wywoływania operacji edycji

Następne jest <selectionColumns />

<selectionsColumn name="ids">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="resizeEnabled" xsi:type="boolean">false</item>
            <item name="resizeDefaultWidth" xsi:type="string">55</item>
            <item name="indexField" xsi:type="string">id</item>
        </item>
    </argument>
</selectionsColumn>

Ten węzeł definiuje kolumnę z polami wyboru do użycia akcji masowej. Nazwy są określane po kropce w kilku opisanych powyżej węzłach.

Następnie możesz dodać dowolną liczbę kolumn w tym samym formacie:

<column name="name" class="Company\Module\Ui\Component\Listing\Column\Name">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Company\Module\Model\Source\Type</item>
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">select</item>
            <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
            <item name="dataType" xsi:type="string">select</item>
            <item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
            <item name="label" xsi:type="string" translate="true">Name</item>
            <item name="sortOrder" xsi:type="number">80</item>
            <item name="visible" xsi:type="boolean">false</item>
        </item>
    </argument>
</column>

Nie wszystkie najbardziej wewnętrzne elementy są potrzebne. Definiują:

filter- typ filtra kolumny. Jest to używane w bloku filtrów. Dostępne wartości to: text, select, dateRange. Jeśli <item name="options">...</item>zostanie użyta opcja select, zostanie użyta jako klasa zapewniająca opcje wyboru filtra

component- definiuje pliki js, które są używane do renderowania kolumny. Dostępne opcje są w Magento/Ui/view/base/web/js/grid/columns/*. pod warunkiem, że wybrano opcję Filtr. W przypadku filtru tekstowego ta wartość nie jest wymagana.

dataType- dostarcza informacji o typie danych użytym dla wartości kolumny. Dla select use również select, dla dateRange use date bodyTmpl- definiuje plik HTML używany przez nokaut do renderowania komórki. Domyślnie używany jest interfejs użytkownika / siatka / komórki / tekst ( Magento/Ui/view/base/web/templates/grid/cells/text.html). Inne opcje znajdują się w Magento/Ui/view/base/web/templates/grid/cells/*katalogu. ui/grid/cells/htmlpozwala na użycie zawartości HTML w komórce.

label - zostanie to wyświetlone w nagłówku kolumny i bloku filtru

sortOrder - zamawianie

visible- czy wyświetla kolumnę, czy nie. Można tego użyć do zdefiniowania kolumn dla zakładek, ale nie wyświetlaj ich domyślnie.

Na koniec możesz dodać kolumnę działań, które można wykonać dla pojedynczego elementu

<actionsColumn name="actions" class="Company\Module\Ui\Component\Listing\Column\Actions">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="resizeEnabled" xsi:type="boolean">false</item>
            <item name="resizeDefaultWidth" xsi:type="string">107</item>
            <item name="indexField" xsi:type="string">database_id</item>
        </item>
    </argument>
</actionsColumn>

indexFieldodnosi się do nazwy kolumny w bazie danych. Klasa akcji powinna rozszerzyć Magento\Ui\Component\Listing\Columns\Columni zdefiniować prepareDataSourcemetodę. Zobacz Magento/Cms/Ui/Component/Listing/Column/PageActions.phpjako odniesienie

3) Aby zakończyć siatkę, musimy zdefiniować niektóre elementy w Company / Module / etc / di.xml

Najpierw definiujemy klasę dostawcy, która została użyta w węźle dataSource/class

<virtualType name="UniqueNameGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
    <arguments>
        <argument name="collection" xsi:type="object" shared="false">Company\Module\Model\Resource\Item\Collection</argument>
        <argument name="filterPool" xsi:type="object" shared="false">UniqueNameItemIdFilterPool</argument>
    </arguments>
</virtualType>

collectionrozwiązuje do standardowej klasy kolekcji i filerPooldefiniuje nowy element:

<virtualType name="UniqueNameItemIdFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
    <arguments>
        <argument name="appliers" xsi:type="array">
            <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
            <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
        </argument>
    </arguments>
</virtualType>

To najwyraźniej ma coś wspólnego z filtrowaniem i wyszukiwaniem. Na razie zawsze korzystałem z wartości domyślnych.

Teraz rejestrujemy nasze źródło danych:

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="listing_name_data_source" xsi:type="string">Company\Module\Model\Resource\Item\Grid\Collection</item>
        </argument>
    </arguments>
</type>

W tym przypadku nazwa węzła musi być zgodna z nazwą użytą w <dataSource />węźle na liście xml i rozwiązuje nie kolekcję, ale klasę GridCollection. Powinien rozszerzyć regularną klasę kolekcji i dodatkowo zaimplementować Magento\Framework\Api\Search\SearchResultInterface.

Na koniec konfigurujemy naszą kolekcję siatki (nazwy argumentów są dość oczywiste)

<type name="Company\Module\Model\Resource\Item\Grid\Collection">
    <arguments>
        <argument name="mainTable" xsi:type="string">database_table_name</argument>
        <argument name="eventPrefix" xsi:type="string">name_for_events</argument>
        <argument name="eventObject" xsi:type="string">event_object_name</argument>
        <argument name="resourceModel" xsi:type="string">Company\Module\Model\Resource\Item</argument>
    </arguments>
</type>


13
Tak dalece, jak widzę, to wciąż pokonuje doktorów.
Aaron Pollock,

2) Interfejs uiComponent jest zdefiniowany w Company / Module / view / adminhtml / ui_component / listing_name.xml. Więc w zasadzie komponent grid nie działa na interfejsie?
Lachezar Raychev

stary post, który znam - ale doszedłem do tego, podążałem za nim (dzięki btw, zdecydowanie jedno z najbardziej szczegółowych wyjaśnień na ten temat), ale dostaję niewyłapany błąd w stosunku do collectionFactory. w szczególności funkcja argumentsResolver. Mówi, że argument 2 powinien być tablicą, ale podano wartość null - zrobiłem wszystkie powyższe - ale czy jest coś jeszcze, co powinienem był zrobić? :)
treyBake

1
@AshishViradiya zaktualizowane linki znajdują się powyżej, w sekcji [EDYCJA 3 października 2018 r.]
Zefiryn

9

Do grid potrzebujemy dwóch głównych plików, jeden to ui_component xml, a drugi to di.xml

Mam nadzieję, że wiesz, że w pliku XML układu musisz dodać znacznik uiComponent, tj. -

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <body>
        <referenceContainer name="content">
            <uiComponent name="test_lists_listing"/>
        </referenceContainer>
    </body>
</page>

teraz musisz utworzyć test_lists_listing.xmlfolder ui_component.

Np. App \ code \ Sugarcode \ Test \ view \ adminhtml \ ui_component \ test_lists_listing.xml

Ten plik ma liczbę tagów

  1. <argument name="data" xsi:type="array"> : - trzeba wspomnieć o arugemnt jak przycisk js itp.
  2. <dataSource name="test_lists_listing_data_source">: - ten blok służy do dostarczania danych do siatek w tym jednym z argumentów, o <argument name="class" xsi:type="string">ListsGridDataProvider</argument>którym musimy wspomnieć di.xml(wyjaśnione w części di.xml )

  3. <container name="listing_top"> : - w tym bloku wymieniamy filtry, eksport, zakładki (które zapisują dane w tabeli ui_bookmark), masowanie, stronicowanie i pełny tekst (aby przeprowadzić wyszukiwanie pełnotekstowe w ustawieniach lub w tabeli, kolumna powinna być indeksem pełnotekstowym)

  4. <columns name="test_lists_columns"> : - w tym musimy wspomnieć całą kolumnę

Ostatni znajduje się w pliku di.xml

<virtualType name="TestGirdFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
    <arguments>
        <argument name="appliers" xsi:type="array">
            <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
            <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
        </argument>
    </arguments>
</virtualType>  


<virtualType name="ListsGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
    <arguments>
        <argument name="collection" xsi:type="object" shared="false">Sugarcode\Test\Model\ResourceModel\Test\Collection</argument>
        <argument name="filterPool" xsi:type="object" shared="false">TestGirdFilterPool</argument>
    </arguments>
</virtualType>  


<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="test_lists_listing_data_source" xsi:type="string">Sugarcode\Test\Model\ResourceModel\Test\Grid\Collection</item>
        </argument>
    </arguments>
</type>
<type name="Sugarcode\Test\Model\ResourceModel\Test\Grid\Collection">
    <arguments>
        <argument name="mainTable" xsi:type="string">testtable</argument>
        <argument name="eventPrefix" xsi:type="string">test_test_grid_collection</argument>
        <argument name="eventObject" xsi:type="string">test_grid_collection</argument>
        <argument name="resourceModel" xsi:type="string">Sugarcode\Test\Model\ResourceModel\Test</argument>
    </arguments>
</type>
  1. TestGirdFilterPool: - wspomnij o filtrach
  2. ListsGridDataProvider: - o którym wspomniałem w interfejsie XML dla dostawcy danych
  3. CollectionFactory: - należy wspomnieć o kolekcji
  4. Siatka / Kolekcja: - w tym musimy przekazać wszystkie parametry, takie jak nazwa tabeli, kolekcja itp.

app \ code \ Sugarcode \ Test \ view \ adminhtml \ ui_component \ test_lists_listing.xml

<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing_data_source</item>
            <item name="deps" xsi:type="string">test_lists_listing.test_lists_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">test_lists_columns</item>
        <item name="buttons" xsi:type="array">
            <item name="add" xsi:type="array">
                <item name="name" xsi:type="string">add</item>
                <item name="label" xsi:type="string" translate="true">Add New Info</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="test_lists_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">ListsGridDataProvider</argument>
            <argument name="name" xsi:type="string">test_lists_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="update_url" xsi:type="url" path="mui/index/render"/>
                </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>
    <container name="listing_top">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="template" xsi:type="string">ui/grid/toolbar</item>
            </item>
        </argument>
        <bookmark name="bookmarks">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="storageConfig" xsi:type="array">
                        <item name="namespace" xsi:type="string">test_lists_listing</item>
                    </item>
                </item>
            </argument>
        </bookmark>
        <exportButton name="export_button">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.ids</item>
                </item>
            </argument>
        </exportButton>
        <container name="columns_controls">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="columnsData" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns</item>
                    </item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
                    <item name="displayArea" xsi:type="string">dataGridActions</item>
                </item>
            </argument>
        </container>
        <filterSearch name="fulltext">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/search/search</item>
                    <item name="displayArea" xsi:type="string">dataGridFilters</item>
                    <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing_data_source</item>
                    <item name="chipsProvider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.listing_filters_chips</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.search</item>
                    </item>
                </item>
            </argument>
        </filterSearch>
        <filters name="listing_filters">

            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="columnsProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.filters</item>
                    </item>
                    <item name="templates" xsi:type="array">
                        <item name="filters" xsi:type="array">
                            <item name="select" xsi:type="array">
                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                                <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                            </item>
                        </item>
                    </item>
                    <item name="childDefaults" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.${ $.index }:visible</item>
                        </item>
                    </item>
                </item>
            </argument>


            <filterSelect name="status">
                <argument name="optionsProvider" xsi:type="configurableObject">
                    <argument name="class" xsi:type="string">Sugarcode\Test\Model\Status</argument>
                </argument>
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="dataScope" xsi:type="string">status</item>
                        <item name="caption" xsi:type="string" translate="true">Select...</item>
                        <item name="label" xsi:type="string" translate="true">Status</item>
                    </item>
                </argument>
            </filterSelect>

        </filters>

        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.ids</item>
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
            <action name="delete">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">delete</item>
                        <item name="label" xsi:type="string" translate="true">Delete</item>
                        <item name="url" xsi:type="url" path="test/lists/massDelete"/>
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">Delete items</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected items?</item>
                        </item>
                    </item>
                </argument>
            </action>
            <action name="edit">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">edit</item>
                        <item name="label" xsi:type="string" translate="true">Edit</item>
                        <item name="callback" xsi:type="array">
                            <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns_editor</item>
                            <item name="target" xsi:type="string">editSelected</item>
                        </item>
                    </item>
                </argument>
            </action>
            <action name="disable">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">disable</item>
                        <item name="label" xsi:type="string" translate="true">Disable</item>
                        <item name="url" xsi:type="url" path="test/lists/massDisable"/>
                    </item>
                </argument>
            </action>
            <action name="enable">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">enable</item>
                        <item name="label" xsi:type="string" translate="true">Enable</item>
                        <item name="url" xsi:type="url" path="test/lists/massEnable"/>
                    </item>
                </argument>
            </action>
        </massaction>

        <paging name="listing_paging">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.paging</item>
                    </item>
                    <item name="selectProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.ids</item>
                    <item name="displayArea" xsi:type="string">bottom</item>
                    <item name="options" xsi:type="array">
                        <item name="20" xsi:type="array">
                            <item name="value" xsi:type="number">20</item>
                            <item name="label" xsi:type="string" translate="true">20</item>
                        </item>
                        <item name="30" xsi:type="array">
                            <item name="value" xsi:type="number">30</item>
                            <item name="label" xsi:type="string" translate="true">30</item>
                        </item>
                        <item name="50" xsi:type="array">
                            <item name="value" xsi:type="number">50</item>
                            <item name="label" xsi:type="string" translate="true">50</item>
                        </item>
                        <item name="100" xsi:type="array">
                            <item name="value" xsi:type="number">100</item>
                            <item name="label" xsi:type="string" translate="true">100</item>
                        </item>
                        <item name="200" xsi:type="array">
                            <item name="value" xsi:type="number">200</item>
                            <item name="label" xsi:type="string" translate="true">200</item>
                        </item>
                    </item>
                </item>
            </argument>
        </paging>
    </container>
    <columns name="test_lists_columns">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="storageConfig" xsi:type="array">
                    <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                    <item name="namespace" xsi:type="string">current</item>
                </item>
                <item name="editorConfig" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.ids</item>
                    <item name="enabled" xsi:type="boolean">true</item>
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="clientConfig" xsi:type="array">
                        <item name="saveUrl" xsi:type="url" path="test/lists/inlineEdit"/>
                        <item name="validateBeforeSave" xsi:type="boolean">false</item>
                    </item>
                </item>

                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.actions</item>
                        <item name="target" xsi:type="string">applyAction</item>
                        <item name="params" xsi:type="array">
                            <item name="0" xsi:type="string">edit</item>
                            <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
                        </item>
                    </item>
                    <item name="controlVisibility" xsi:type="boolean">true</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                        <item name="root" xsi:type="string">columns.${ $.index }</item>
                        <item name="namespace" xsi:type="string">current.${ $.storageConfig.root }</item>
                    </item>
                </item>
            </item>
        </argument>     
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="sortOrder" xsi:type="number">0</item>
                </item>
            </argument>
        </selectionsColumn> 
        <column name="id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">textRange</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </column>   
         <column name="order_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="filter_index" xsi:type="string">o.increment_id</item>
                    <item name="add_field" xsi:type="boolean">false</item>
                    <item name="label" xsi:type="string" translate="true">Order ID</item>
                    <item name="sortOrder" xsi:type="number">20</item>
                </item>
            </argument>
        </column>       
        <column name="title">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">text</item>
                        <item name="validation" xsi:type="array">
                            <item name="required-entry" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Title</item>
                    <item name="sortOrder" xsi:type="number">30</item>
                </item>
            </argument>
        </column>

        <column name="status">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Sugarcode\Test\Model\Status</item>
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                    <item name="editor" xsi:type="string">select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Status</item>
                    <item name="sortOrder" xsi:type="number">40</item>
                </item>
            </argument>
        </column>   


        <column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">dateRange</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                    <item name="dataType" xsi:type="string">date</item>
                    <item name="label" xsi:type="string" translate="true">Created</item>
                    <item name="sortOrder" xsi:type="number">50</item>
                </item>
            </argument>
        </column>

        <actionsColumn name="actions" class="Sugarcode\Test\Ui\Component\Listing\Column\TestActions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

SortOrder nie działa dla selectionsColumn. Nie
zastanawiaj się,

6

Suplement do najlepszej odpowiedzi

Najlepsza odpowiedź jest świetna, śledzę ją, aby utworzyć stronę z listą. Ale ma problem :

Gdy zastosujesz filtr, a następnie usuniesz filtr, ta sama treść wiersza powtórzy się w całej siatce strony .

Rozwiązanie

W <dataSource />węźle poniżej <item name="update_url" xsi:type="url" path="mui/index/render"/>dodaj treść:

<item name="storageConfig" xsi:type="array">
    <item name="indexField" xsi:type="string">entity_id</item>
</item>

entity_id jest podstawowym kluczem do zbioru list.


4

Uważam, że odpowiedź @ Zefiryn jest bardzo pomocna i świetna, jak zacząć bez czytania pełnej dokumentacji z Magento.

To powiedziawszy, że po tych odpowiedziach nie działało mi całkiem dobrze. Co więcej, gdy już uruchomisz stronę z listą, od razu będziesz potrzebować pozostałej części interfejsu CRUD.

Znalazłem przykładowy moduł na github . Zaczynając od tego wątku służącego do orientacji, okazało się, że portowanie / hakowanie kodu z przykładowej wtyczki jest najszybszym sposobem uzyskania interfejsu CRUD dla niestandardowej tabeli.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.