Explicación de la cuadrícula de componentes de la interfaz de usuario en Magento 2

91

¿Existe una buena explicación y / o muestra de la configuración mínima básica necesaria para crear una cuadrícula de componentes de la interfaz de usuario en Magento 2?

Sé que hay innumerables componentes principales, como

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

Sin embargo, estos archivos XML son expansivos y hay poca explicación sobre lo que hace cada nodo y cómo usaría esto para construir una cuadrícula desde cero.

También hay este módulo de muestra , pero

  1. Parece ser antes de un formulario
  2. Carece de contexto / explicación sobre lo que hace cada nodo

Estoy buscando la información de "inicio" que me permita crear una cuadrícula para mi propia colección de modelos CRUD.

Alan Storm
fuente
66
No vale la pena una respuesta completa, pero mi serie de componentes UI es un buen lugar para comenzar: alanstorm.com/category/magento-2/#magento-2-ui
Alan Storm

Respuestas:

167

[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.xmlcuadrí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.xmlarchivo. 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 datadefine información básica sobre el componente. Contiene múltiples <item />nodos para cada parte específica de la configuración. js_configle 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). providerEl 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 providery depsson lo mismo. No estoy seguro de qué sirve tener esto diferente. spinnertoma el nombre del nodo donde se definen las columnas de la cuadrícula. buttonspermite agregar botones a la parte superior de la cuadrícula. En la mayoría de los casos sería solo un Add newbotón. Los botones tienen pocos elementos:nameusado como id de elemento, labeles lo que dice el botón, classes la clase de botón y urles 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\Buttonclase.

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>

nameusado en el <dataSource />nodo debe coincidir con el usado en argument/js_config/providery argument/js_config/deps. El siguiente nodo define qué clase es responsable de preparar los datos para la cuadrícula. classEl argumento requiere un nombre único que coincida di.xml. primaryFieldNamese relaciona con la columna primaria de la base de datos y requestFieldNamecon la variable en las solicitudes http. Pueden ser iguales, pero no es necesario, la lista de páginas de CMS usa page_idas primaryFieldNamey idas requestFieldName. update_urlse 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. namespacedebe 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 providerque sigue el patrón [listing_name_from_layout]. [Listing_name_from_layout]. [Listing_columns_node_name] (como en el listado de nodos / argumento / spinner). componentse 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.jsque se usa la plantilla Magento/Ui/view/base/web/templates/grid/controls/columns.html. El último elemento es el displayAreaque 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.jsarchivo.

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. columnsProvidersigue una estructura similar a los nodos anteriores, por lo que [listing_name_from_layout]. [listing_name_from_layout]. [listing_columns_node_name]. storegeConfigva como [listing_name_from_layout]. [listing_name_from_layout]. [container_node_name] [bookmark_node_name]. En templatesel 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.jscomo componenty Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.htmlcomo plantilla de eliminación. Mira Magento/Ui/view/base/web/js/form/elementpara ver otras posibilidades. Aquí solo se define select para anular los valores predeterminados: Magento/Ui/view/base/web/js/form/element/select.jsy 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>

nameEl argumento debe ser único. El primer nodo hijo <argument />define datos básicos. providersigue 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. componentdefine 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-massactionspara 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 argumentcontiene la configuración dondelabeles lo que está visible en la opción de selección, urlpunto final para enviar datos y confirmagrega modal de confirmación antes de enviar. En caso de "Cambiar estado", se omite la acción urlen el primer argumentnodo ya que las URL se proporcionan por estado por clase definida en el segundo argumentnodo. La clase debe implementar la interfaz Zend \ Stdlib \ JsonSerializable. Verificar Magento\Customer\Ui\Component\MassAction\Group\Optionscomo 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 providery selectProviderdebe 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 providervalores correctos siguiendo el esquema utilizado en la lista. fieldActionEl 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/htmlpermite 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>

indexFieldse refiere al nombre de la columna en la base de datos. La clase de acciones debe extender Magento\Ui\Component\Listing\Columns\Columny definir el prepareDataSourcemétodo. Ver Magento/Cms/Ui/Component/Listing/Column/PageActions.phpcomo 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>

collectionresuelve la clase de colección estándar y filerPooldefine 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>
Zefiryn
fuente
1
¿
Tuviste
13
Esto todavía supera a los documentos por un largo camino, por lo que puedo ver.
Aaron Pollock
2) uiComponent se define en Company / Module / view / adminhtml / ui_component / listing_name.xml. Entonces, básicamente, ¿el componente de cuadrícula no funciona en la interfaz?
Lachezar Raychev
publicación anterior lo sé, pero he llegado a esto, lo seguí (gracias, por cierto, definitivamente una de las explicaciones más detalladas sobre esto) pero recibo un error no detectado en relación con la colección Factory. específicamente la función argumentosResolver. Dice que el argumento 2 debería ser una matriz, pero se da un valor nulo: he hecho todo lo anterior, pero ¿hay algo más que debería haber hecho? :)
treyBake
1
@AshishViradiya los enlaces actualizados están arriba, en la sección [EDITAR 3 de octubre de 2018]
Zefiryn
9

Para la grilla necesitamos dos archivos principales, uno es ui_component xml y el segundo es di.xml

Espero que sepa en el archivo xml de diseño que necesita agregar la etiqueta uiComponent, es decir,

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

ahora necesita crear una test_lists_listing.xmlcarpeta ui_component.

Por ejemplo, app \ code \ Sugarcode \ Test \ view \ adminhtml \ ui_component \ test_lists_listing.xml

Este archivo tiene varias etiquetas

  1. <argument name="data" xsi:type="array"> : - Necesito mencionar arugemnt como botón js etc.
  2. <dataSource name="test_lists_listing_data_source">: - este bloque se usa para proporcionar datos para cuadrículas en este uno de los argumentos <argument name="class" xsi:type="string">ListsGridDataProvider</argument>que debemos mencionar di.xml(explicado en la parte di.xml )

  3. <container name="listing_top"> : - en este bloque mencionamos filtros, exportación, marcadores (que guardan datos en la tabla ui_bookmark), masajes, paginación y texto completo (para realizar una búsqueda de texto completo en la configuración o tabla, esa columna debe ser el índice de texto completo)

  4. <columns name="test_lists_columns"> : - en esto necesitamos mencionar todas las columnas

El último está en 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: - mencionar filtros
  2. ListsGridDataProvider: que mencioné en ui xml para el proveedor de datos
  3. CollectionFactory: - es necesario mencionar colección
  4. Cuadrícula / Colección: en esto necesitamos pasar todos los parámetros como el nombre de la tabla, la colección, etc.

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>
Pradeep Kumar
fuente
sortOrder no funciona para selectionsColumn. No sé por qué viene al fin
Bhupendra Jadeja
6

El suplemento de la respuesta principal

La respuesta principal es excelente, la sigo para crear una página de listado. Pero tiene un problema :

Cuando aplica el filtro y luego elimina el filtro, el mismo contenido de fila se repetirá en toda la cuadrícula de la página .

Solución

En el <dataSource />nodo, a continuación <item name="update_url" xsi:type="url" path="mui/index/render"/>, agregue el contenido:

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

entity_id es la clave principal para la colección de listado.

Key Shang
fuente
4

Encontré la respuesta de @ Zefiryn muy útil y una excelente manera de comenzar sin leer la documentación completa de Magento.

Dicho esto, no conseguí que las cosas funcionen del todo después de estas respuestas. Además, una vez que tenga una página de listado funcionando, inmediatamente querrá el resto de una interfaz CRUD.

Encontré un módulo de muestra en github . Comenzar con este hilo para orientación y luego portar / piratear el código del complemento de muestra resultó ser la forma más rápida de obtener una interfaz CRUD contra una tabla personalizada.

quickshiftin
fuente