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