[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.xml
definiuje 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.xml
pliku. 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 data
określa podstawowe informacje o komponencie. Zawiera wiele <item />
węzłów dla każdej określonej części konfiguracji. js_config
informuje komponent, gdzie są dostawcy danych i zależności w konfiguracji listingu xml (co myślę, że jest konwertowane na hash javascript). provider
wartość 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 provider
i deps
są takie same. Nie jestem pewien, jaki pożytek z posiadania tego innego. spinner
przyjmuje nazwę węzła, w którym zdefiniowano kolumny siatki. buttons
pozwala dodawać przyciski na górze siatki. W większości przypadków byłby to tylko Add new
przycisk. Przyciski mają kilka elementów:name
używany jako identyfikator elementu, label
to, co mówi przycisk, class
jest klasą przycisku i url
jest 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\Button
klasy.
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>
name
użyte w <dataSource />
węźle musi być zgodne z tym używanym w argument/js_config/provider
i argument/js_config/deps
. Następny węzeł określa, która klasa jest odpowiedzialna za przygotowanie danych do siatki. class
argument wymaga unikalnej nazwy, która zostanie dopasowana di.xml
. primaryFieldName
odnosi się do podstawowej kolumny bazy danych i requestFieldName
zmiennej w żądaniach HTTP. Mogą być równe, ale nie muszą, lista stron CMS używa page_id
jako primaryFieldName
i id
jako requestFieldName
. update_url
odnosi 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. namespace
musi 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 provider
nastę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). component
odnosi się do pliku js, który wyświetla siatkę i domyślnie wskazuje punkty, do Magento/Ui/view/base/web/js/grid/controls/columns.js
których wykorzystuje szablon Magento/Ui/view/base/web/templates/grid/controls/columns.html
. Ostatni element displayArea
okreś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.js
pliku.
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ą. columnsProvider
ma podobną strukturę jak poprzednie węzły, więc [nazwa_listy_z gry]. [nazwa_listy z gry]. [nazwa_kolekcji_listy]. storegeConfig
wygląda jak [nazwa_wpisu_z gry]. [nazwa_wpisu z gry]. [nazwa_węzła kontenera] [nazwa_węzła zakładki]. W templates
węź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.js
jako component
i Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html
jako szablonu nokautu. Sprawdź, Magento/Ui/view/base/web/js/form/element
aby 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.js
i 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>
name
argument powinien być unikalny. Pierwszy węzeł potomny <argument />
definiuje podstawowe dane. provider
ma 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ą. component
okreś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-massactions
aby 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 argument
zawiera konfigurację gdzielabel
jest widoczny w opcji select, url
punkcie końcowym do wysłania danych i confirm
dodaje modalne potwierdzenie przed wysłaniem. W przypadku „Zmień status” akcja url
w pierwszym argument
węźle jest zalecana, ponieważ adresy URL są podawane według statusu według klasy zdefiniowanej w drugim argument
węźle. Klasa powinna implementować interfejs Zend \ Stdlib \ JsonSerializable. Sprawdź Magento\Customer\Ui\Component\MassAction\Group\Options
jako 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 provider
i selectProvider
powinna 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 provider
wartości tylko zgodnie ze schematem zastosowanym na liście. fieldAction
wę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/html
pozwala 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>
indexField
odnosi się do nazwy kolumny w bazie danych. Klasa akcji powinna rozszerzyć Magento\Ui\Component\Listing\Columns\Column
i zdefiniować prepareDataSource
metodę. Zobacz Magento/Cms/Ui/Component/Listing/Column/PageActions.php
jako 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>
collection
rozwiązuje do standardowej klasy kolekcji i filerPool
definiuje 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>