[EDITAR 3 de octubre de 2018]
Actualización para enlaces a devdocs: 2.0 - https://devdocs.magento.com/guides/v2.0/ui-components/ui-listing-grid.html y https://devdocs.magento.com/guides/v2. 0 / ui-components / ui -dary.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
[EDITAR 21 de enero de 2016]
A partir del 20/01/2016, los devdocs de magento2 se han actualizado con documentación ampliada de los componentes de la interfaz de usuario. No lo he revisado exhaustivamente, pero pueden contener más información que la respuesta que di hace unos días, por lo que, en interés de su tiempo, es posible que desee ver http://devdocs.magento.com/guides/v2.0/ui -library / ui-library -dary.html
[/EDITAR]
Llevo más de un mes trabajando con Magento2 y esto es lo que noté sobre la nueva forma de crear cuadrículas.
Componente de cuadrícula Magento 2 UI
1) el archivo de diseño dentro de la Company/Module/view/adminhtml/layout/module_controller_action.xml
cuadrícula definida como uiComponent con:
<?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 se define en el Company/Module/view/adminhtml/ui_component/listing_name.xml
archivo. El nombre del archivo debe ser el mismo que el nombre del componente ui utilizado en el archivo de diseño. La estructura del archivo puede parecer bastante compleja a primera vista, pero como siempre, estos son algunos nodos repetidos. Para hacerlo simple, vamos a cortarlo. El nodo principal del archivo componente es <listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
. Está arreglado y creo que requiere un atributo de ubicación de espacio de nombres. A continuación son típicamente 4 nodos dentro de <listing />
nodo: <argument />
, <dataSource />
, <container />
y <columns />
. Sin embargo, esta no es una configuración estricta, ya que el <argument />
nodo podría duplicarse para proporcionar más configuración o <container />
como en la lista de páginas de cms que agrega un contenedor "fijo" por alguna razón.
El primer nodo es <argument />
. Este nodo define datos para el componente. Por lo general, debe proporcionar algo como esto:
<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 />
El nodo requiere atributo name
. En este caso data
define información básica sobre el componente. Contiene múltiples <item />
nodos para cada parte específica de la configuración. js_config
le dice al componente dónde está el proveedor de los datos y las dependencias en la configuración xml de la lista (que creo que se convierte en hash de JavaScript). provider
El valor consiste en el nombre del listado utilizado en el archivo de diseño y el nombre de la fuente de datos uniqure que se usará más adelante. En esos listados revisé en magento provider
y deps
son lo mismo. No estoy seguro de qué sirve tener esto diferente. spinner
toma el nombre del nodo donde se definen las columnas de la cuadrícula. buttons
permite agregar botones a la parte superior de la cuadrícula. En la mayoría de los casos sería solo un Add new
botón. Los botones tienen pocos elementos:name
usado como id de elemento, label
es lo que dice el botón, class
es la clase de botón y url
es el enlace al que apunta. Los asteriscos se reemplazan por la parte de la URL actual. Otros posibles <item />
nodos de botón son: id
, title
, type
(reset, botón de envío o), onclick
(en lugar de url
, tiene precedencia), style
, value
, disabled
. El elemento del botón se representa por Magento\Ui\Component\Control\Button
clase.
A continuación tenemos <dataSource />
nodo:
<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
usado en el <dataSource />
nodo debe coincidir con el usado en argument/js_config/provider
y argument/js_config/deps
. El siguiente nodo define qué clase es responsable de preparar los datos para la cuadrícula. class
El argumento requiere un nombre único que coincida di.xml
. primaryFieldName
se relaciona con la columna primaria de la base de datos y requestFieldName
con la variable en las solicitudes http. Pueden ser iguales, pero no es necesario, la lista de páginas de CMS usa page_id
as primaryFieldName
y id
as requestFieldName
. update_url
se refiere al punto de entrada donde se envían las llamadas ajax para filtrado y clasificación. El segundo argumento se <dataSource />
refiere al archivo javascript que maneja js parte del envío y procesamiento de llamadas ajax para la cuadrícula. El archivo predeterminado es Magento/Ui/view/base/web/js/grid/provider.js
.
Otro nodo es <container />
.
<container name="listing_top"> ... </container>
Como contiene muchos datos, permítanme dividirlos también. Sus hijos son las partes de toda la página. Primer hijo <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>
Define la plantilla de eliminación responsable de manejar el diseño y todas las acciones y, por defecto, apunta a Magento/Ui/view/base/web/templates/grid/toolbar.html
El siguiente nodo es (o puede ser) <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>
Este nodo agrega la función de marcador a la cuadrícula. Permite al administrador configurar diferentes "perfiles" de la cuadrícula que muestra diferentes columnas. Gracias a eso, puede agregar todas las columnas de la tabla a la cuadrícula y dejar que el usuario decida qué información es relevante para él. namespace
debe coincidir con el nombre utilizado en el archivo de diseño.
Otro nodo es <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>
Tenemos 3 valores para configurar aquí. Primero es el provider
que sigue el patrón [listing_name_from_layout]. [Listing_name_from_layout]. [Listing_columns_node_name] (como en el listado de nodos / argumento / spinner). component
se refiere al archivo js que muestra la cuadrícula y, de forma predeterminada, puntos a los Magento/Ui/view/base/web/js/grid/controls/columns.js
que se usa la plantilla Magento/Ui/view/base/web/templates/grid/controls/columns.html
. El último elemento es el displayArea
que define dónde deben mostrarse los controles de columna. Se refiere al getRegion('dataGridActions')
archivo definido en container/argument/config/template
(predeterminado:) Magento/Ui/view/base/web/templates/grid/toolbar.html
.
El siguiente nodo es <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>
Este nodo agrega búsqueda de texto completo en la página. Se encuentra encima de la cuadrícula como campo de entrada de texto único con "Buscar por palabra clave" como marcador de posición. No estoy seguro de qué opciones son posibles aquí, ya que no jugué tanto, pero listing_filters_chips se refiere al Magento/Ui/view/base/web/js/grid/filters/chips.js
archivo.
El siguiente nodo es <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>
Este nodo define la configuración para el filtrado de columnas que es visible después de hacer clic en el botón "Filtros" en la esquina superior derecha encima de la cuadrícula. columnsProvider
sigue una estructura similar a los nodos anteriores, por lo que [listing_name_from_layout]. [listing_name_from_layout]. [listing_columns_node_name]. storegeConfig
va como [listing_name_from_layout]. [listing_name_from_layout]. [container_node_name] [bookmark_node_name]. En templates
el nodo del elemento, puede definir qué archivos se utilizan para representar opciones de filtro específicas. En este caso, solo se define select y se usa Magento/Ui/view/base/web/js/form/element/ui-select.js
como component
y Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html
como plantilla de eliminación. Mira Magento/Ui/view/base/web/js/form/element
para ver otras posibilidades. Aquí solo se define select para anular los valores predeterminados: Magento/Ui/view/base/web/js/form/element/select.js
y Magento/Ui/view/base/web/templates/grid/filters/elements/select.html
. Los valores predeterminados para filtros y otros nodos se definen en Magento/Ui/view/base/ui_component/etc/definition.xml
.
El siguiente nodo es <massAction />
y permite agregar acciones masivas seleccionadas a la cuadrícula
<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
El argumento debe ser único. El primer nodo hijo <argument />
define datos básicos. provider
sigue la misma estructura que otros nodos y hace referencia al nombre del nodo de las columnas y su columna de identificadores. Esta columna mantendrá casillas de verificación con elementos seleccionados para que la acción masiva se procese. component
define qué archivo se usa para representar y manejar la acción en masa. El valor predeterminado es Magento_Ui/js/grid/massactions
(apunta a Magento/Ui/view/base/web/js/grid/massactions.js
). Puede usar Magento_Ui/js/grid/tree-massactions
para agregar estructura tipo árbol. En el caso anterior, lo uso para agregar la acción "Cambiar estado" que muestra las opciones "habilitar" y "deshabilitar". Después del <argument />
nodo, puede agregar tantos <action />
nodos como tantas acciones que desee tener. Cada <action />
nodo sigue un esquema similar. En el primer caso (acción de eliminación), el nodo requiere un nombre único. Luego argument
contiene la configuración dondelabel
es lo que está visible en la opción de selección, url
punto final para enviar datos y confirm
agrega modal de confirmación antes de enviar. En caso de "Cambiar estado", se omite la acción url
en el primer argument
nodo ya que las URL se proporcionan por estado por clase definida en el segundo argument
nodo. La clase debe implementar la interfaz Zend \ Stdlib \ JsonSerializable. Verificar Magento\Customer\Ui\Component\MassAction\Group\Options
como referencia.
Finalmente en el <container />
nodo tenemos un <paging />
nodo que define la paginación.
<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>
Estructura para provider
y selectProvider
debe estar claro ahora.
Y el último nodo para la cuadrícula básica es <columns />
. Contiene todas las definiciones de columnas que están disponibles para que las use el administrador. El nodo se define como
<columns name="listing_columns"> ... </columns>
y el atributo de nombre se usa en otros nodos cuando se refiere a él. Primer hijo es
<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>
Lo que hice aquí fue solo proporcionar provider
valores correctos siguiendo el esquema utilizado en la lista. fieldAction
El nodo permite definir la acción que se dispara cuando se hace clic en la celda. Configuración predeterminada llamada acción de edición
El siguiente es <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>
Este nodo define la columna con casillas de verificación para la acción masiva a utilizar. Su nombre se menciona después del punto en varios nodos descritos anteriormente.
Después de eso, puede agregar cualquier número de columnas en el mismo formato:
<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>
No todos los nodos de elementos más internos son necesarios. Ellos están definiendo:
filter
- tipo de filtro de la columna. Esto se usa en el bloque de filtros. Los valores disponibles son: texto, select, dateRange. Si se usa select se usará <item name="options">...</item>
como una clase que proporciona opciones para el filtro select
component
- define archivos js que se utilizan para representar la columna. Las opciones disponibles están en Magento/Ui/view/base/web/js/grid/columns/*
. se proporciona seleccionar si el filtro está configurado para seleccionar. Para el filtro de texto, este valor no es obligatorio.
dataType
- proporciona información del tipo de datos utilizado para el valor de la columna. Para select use select también, para dateRange use date
bodyTmpl
: define el archivo html utilizado por knockout para representar la celda. Por defecto se usa ui / grid / cells / text ( Magento/Ui/view/base/web/templates/grid/cells/text.html
). Otras opciones se encuentran en el Magento/Ui/view/base/web/templates/grid/cells/*
directorio. ui/grid/cells/html
permite usar contenido html en la celda.
label
- esto se mostrará en el encabezado de columna y el bloque de filtro
sortOrder
- pedido
visible
- si se muestra o no la columna. Esto se puede utilizar para definir columnas para marcadores, pero no las muestra de forma predeterminada.
Al final, puede agregar acciones a la columna de acciones de brujas disponibles para el elemento individual
<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
se refiere al nombre de la columna en la base de datos. La clase de acciones debe extender Magento\Ui\Component\Listing\Columns\Column
y definir el prepareDataSource
método. Ver Magento/Cms/Ui/Component/Listing/Column/PageActions.php
como referencia
3) para terminar la grilla necesitamos definir algunos elementos en Company / Module / etc / di.xml
Primero definimos la clase de proveedor que se usó en el nodo 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
resuelve la clase de colección estándar y filerPool
define un nuevo elemento:
<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>
Evidentemente, esto tiene que ver con el filtrado y la búsqueda. Por ahora siempre usé los valores predeterminados.
Ahora registramos nuestra fuente de datos:
<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>
En este caso, el nombre del nodo debe coincidir con el utilizado en el <dataSource />
nodo en la lista de xml y se resuelve no en la colección sino en la clase GridCollection. Debe extender la clase de colección regular e implementar adicionalmente Magento\Framework\Api\Search\SearchResultInterface
.
Al final configuramos nuestra colección de grillas (los nombres de los argumentos son bastante obvios)
<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>